Hello,
i have a question again.
I have a number, example 123456789 or 123456789,00
How i can display it whit thousands separators, example 123.456.789 or 123.456.789,00
Have Rainmeter a funktion for this included?
If not, what way can do this?
greeting Indy
It is currently May 4th, 2024, 7:23 am
thousands separator
-
- Posts: 40
- Joined: August 8th, 2013, 10:40 pm
-
- Developer
- Posts: 22631
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: thousands separator
There is no built-in function for this in Rainmeter. The only way I can think of to approach it and get both the separators, and in the "locale" format you suggest, is to use a Lua script.Indy wrote:Hello,
i have a question again.
I have a number, example 123456789 or 123456789,00
How i can display it whit thousands separators, example 123.456.789 or 123.456.789,00
Have Rainmeter a funktion for this included?
If not, what way can do this?
greeting Indy
FormatNumber.ini
Code: Select all
[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1
[Variables]
Separator="."
Decimal=","
[MeasureFormatNumber]
Measure=Script
ScriptFile=FormatNumber.lua
UpdateDivider=-1
[MeasureDriveCTotal]
Measure=FreeDiskSpace
Drive=C:
Total=1
IgnoreRemovable=0
UpdateDivider=5
OnUpdateAction=[!CommandMeasure MeasureFormatNumber "FormatNumber('DriveCTotal', '[MeasureDriveCTotal]', '#Separator#', '#Decimal#')"]
DynamicVariables=1
[MeterDriveCTotal]
Meter=String
MeasureName=MeasureDriveCTotal
FontSize=13
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Text=Unformatted - %1#CRLF#Formatted - #DriveCTotal#
DynamicVariables=1
Code: Select all
function FormatNumber(varName, inNum, sepChar, decChar)
local outNum = inNum
local replaceCount = 0
outNum = outNum:gsub('^(.-)%D(.-)$', '%1'..decChar..'%2')
while true do
outNum, replaceCount = outNum:gsub('^(-?%d+)(%d%d%d)', '%1'..sepChar..'%2')
if (replaceCount == 0) then
break
end
end
SKIN:Bang('!SetVariable', varName, outNum)
end
Simply set the character you want as the separator in the [Variable] Separator="SomeChar", and the character to use to delimit decimal places in Decimal="SomeChar".
The !CommandMeasure bang to Lua will take as input to the function the variable to set, the input value as a string or a [SectionVariable], the separator as a string, and the decimal place delimiter as a string. This is in the format:
[!CommandMeasure ScriptMeasureName "FormatNumber('VariableToSet', 'InputValue', 'Separator', 'DecimalDelimiter')"]
All parameters are required.
When the measure with the OnUpdateAction fires the Lua script with !CommandMeasure, the number will be formatted, and the variable will dynamically be set in the skin. You can then use that variable dynamically in any output meter you desire.
The skin and example above uses the FreeDiskSpace measure as a working example. However, it doesn't demonstrate the setting of the decimal place delimiter. The following test skin does:
Code: Select all
[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1
[Variables]
Separator="."
Decimal=","
[MeasureFormatNumber]
Measure=Script
ScriptFile=FormatNumber.lua
UpdateDivider=-1
[MeasureBigNumber]
Measure=Time
Format=123456789.1234
UpdateDivider=5
OnUpdateAction=[!CommandMeasure MeasureFormatNumber "FormatNumber('BigNumber', '[MeasureBigNumber]', '#Separator#', '#Decimal#')"]
DynamicVariables=1
[MeterBigNumber]
Meter=String
MeasureName=MeasureBigNumber
FontSize=13
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Text=Unformatted - %1#CRLF#Formatted - #BigNumber#
DynamicVariables=1
If you haven't already run away screaming, I'm glad to answer any questions about how and why this works. It looks more complicated than it really is.
You do not have the required permissions to view the files attached to this post.
-
- Posts: 40
- Joined: August 8th, 2013, 10:40 pm
Re: thousands separator
Hello,
thank you very much for your help.
I tried to implement it in my Project.
What i do?
The unformatted number come from
as a number whit 9 digits (example 123456789)
firstly add
to my Variables
secondly add
thirdly add
And the Output
The output in the Skin is now
Skill Points: Unformatted - 00:15:18 (i think is the Windows Time)
Formatted - 123.456.789 (the right 9 digits number now formatted)
Now i have questions to this.
The Measure=Time is not need for this?
If i change Measure=Time to Measure=anything, i become an error:
Measure=anything is not Valid in[MeasureSkillPoints]
How i become this Output?
Skill Points: Unformatted - 123456789 (the right 9 digits number from input, unformatted)
Formatted - 123.456.789 (the right 9 digits number from input, formatted)
It work fine for format my number, but i dont understand Measure=Time thing.
Sorry for some questions, but I do not see my error.
greeting Indy
thank you very much for your help.
I tried to implement it in my Project.
What i do?
The unformatted number come from
Code: Select all
[MeasureSP3]
Measure=Plugin
Plugin=Plugins\WebParser.dll
Url=[MeasureCharacterInfo3]
StringIndex=2
MinValue=0
MaxValue=441344000
DynamicVariables=1
firstly add
Code: Select all
Separator="."
Decimal=","
secondly add
Code: Select all
[MeasureFormatNumber]
Measure=Script
ScriptFile=FormatNumber.lua
UpdateDivider=-1
Code: Select all
[MeasureSkillPoints]
Measure=Time
UpdateDivider=5
OnUpdateAction=[!CommandMeasure MeasureFormatNumber "FormatNumber('SkillPoints', '[MeasureSP3]', '#Separator#', '#Decimal#')"]
DynamicVariables=1
Code: Select all
[MeterSP4]
Meter=STRING
MeasureName=MeasureSkillPoints
MeterStyle= styleBodyText
X = 5
Y = 155
Text=Skill Points: Unformatted - %1#CRLF#Formatted - #SkillPoints#
DynamicVariables=1
Skill Points: Unformatted - 00:15:18 (i think is the Windows Time)
Formatted - 123.456.789 (the right 9 digits number now formatted)
Now i have questions to this.
The Measure=Time is not need for this?
If i change Measure=Time to Measure=anything, i become an error:
Measure=anything is not Valid in[MeasureSkillPoints]
How i become this Output?
Skill Points: Unformatted - 123456789 (the right 9 digits number from input, unformatted)
Formatted - 123.456.789 (the right 9 digits number from input, formatted)
It work fine for format my number, but i dont understand Measure=Time thing.
Sorry for some questions, but I do not see my error.
greeting Indy
-
- Developer
- Posts: 22631
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: thousands separator
The Time measure was just an example to show how to format a number with decimal places in it. I just demonstrated with a Time measure as you can put any string in the Format option, so it is a good measure type for easy testing of stuff like this.
In your case, you can
Note that I put this in a Calc measure that uses [MeasureSP3] as the input for the Formula, since you seem to have some other need for a MinValue / MaxValue based on the number (this is right if you later want to use it in a Bar or Line or Rotator meter for example, which require a "percentage" based on the range of minimum and maximum).
However, you can't use MinValue or MaxValue on a WebParser measure, as WebParser only returns "strings", (even if it looks like a number) and not "real numbers". Using a Calc measure with the current value of the WebParser measure as the Formula will convert the string into a "real number", that you can do calculations on (like setting a MinValue and MaxValue).
If on the other hand, you don't actually need to set MinValue / MaxValue, (and don't want to use IFActions on the value, or perform some calculation on the value, or anything else that requires a real number) then there is no reason why you can't put the OnChangeAction (see below for why I made it OnChangeAction instead of OnUpdateAction) right on the WebParser measure, as the Lua function is just treating the number as a string in any case.
----------------
Just one other hint that is specific to doing this with WebParser.
The reason I used OnUpdateAction to execute the !CommandMeasure was to be able to control how often the script was actually run by setting UpdateDivider on the measure (the FreeDiskSpace measure in my example). I don't want to check the drive and run the script every Update (which would be once a second with Update=1000 in [Rainmeter]) as that is just excessive for that kind of value.
Now with WebParser, you control how often the site is accessed and the HTML read using a different option. You use UpdateRate, which defaults to 600, or every 10 minutes when Update=1000. Generally speaking, hitting a site every 10 minutes is plenty often.
However the WebParser measure itself will still "update" based on the Update value in [Rainmeter], even though by default the UpdateRate is telling only to hit the site every 10 minutes. If we use OnUpdateAction to run the !CommandMeasure bang in the calc measure, we are running the script once a second, when the value of the measure is certain to change at BEST once every 10 minutes.
That is just hideously inefficient. It won't hurt anything really, but offends me.
Still, we want to keep the actual update of the value from the site in "sync" with the running of the Lua script, so we don't want to just add an UpdateDivider=600 to the Calc measure or something, as that won't really tie the two (the WebParser and the Calc) together, just get them "close" as far as timing.
So, instead I used OnChangeAction in the Calc measure to run the !CommandMeasure bang. That way, the Lua script is only run when the value of the Calc measure is actually changed, which will only be when the WebParser measure goes out and gets a value from the web site that is different than what it was 10 minutes ago.
I set the initial state of the meter [MeterSP3] to Hidden=1, so it doesn't display invalid values before the WebParser measure has a chance to get the information from the web site. I use FinishAction=[!ShowMeter MeterSP3] on the WebParser measure to "unhide" the meter when the measure has finished getting and parsing the site.
Hope that makes sense. It's not a big deal, but it is the "right" way to do it.
In your case, you can
Code: Select all
[MeasureSP3]
Measure=Plugin
Plugin=Plugins\WebParser.dll
Url=[MeasureCharacterInfo3]
StringIndex=2
OnFinishAction=[!ShowMeter MeterSP3]
[MeasureSP3Number]
Measure=Calc
Formula=[MeasureSP3]
MinValue=0
MaxValue=441344000
OnChangeAction=[!CommandMeasure MeasureFormatNumber "FormatNumber('SkillPoints', '[MeasureSP3Number]', '#Separator#', '#Decimal#')"]
DynamicVariables=1
[MeterSP3]
Meter=String
MeasureNameMeasureSP3Number
MeterStyle=styleBodyText
X=5
Y=155
Text=Skill Points: Unformatted - %1#CRLF#Formatted - #SkillPoints#
Hidden=1
DynamicVariables=1
However, you can't use MinValue or MaxValue on a WebParser measure, as WebParser only returns "strings", (even if it looks like a number) and not "real numbers". Using a Calc measure with the current value of the WebParser measure as the Formula will convert the string into a "real number", that you can do calculations on (like setting a MinValue and MaxValue).
If on the other hand, you don't actually need to set MinValue / MaxValue, (and don't want to use IFActions on the value, or perform some calculation on the value, or anything else that requires a real number) then there is no reason why you can't put the OnChangeAction (see below for why I made it OnChangeAction instead of OnUpdateAction) right on the WebParser measure, as the Lua function is just treating the number as a string in any case.
----------------
Just one other hint that is specific to doing this with WebParser.
The reason I used OnUpdateAction to execute the !CommandMeasure was to be able to control how often the script was actually run by setting UpdateDivider on the measure (the FreeDiskSpace measure in my example). I don't want to check the drive and run the script every Update (which would be once a second with Update=1000 in [Rainmeter]) as that is just excessive for that kind of value.
Now with WebParser, you control how often the site is accessed and the HTML read using a different option. You use UpdateRate, which defaults to 600, or every 10 minutes when Update=1000. Generally speaking, hitting a site every 10 minutes is plenty often.
However the WebParser measure itself will still "update" based on the Update value in [Rainmeter], even though by default the UpdateRate is telling only to hit the site every 10 minutes. If we use OnUpdateAction to run the !CommandMeasure bang in the calc measure, we are running the script once a second, when the value of the measure is certain to change at BEST once every 10 minutes.
That is just hideously inefficient. It won't hurt anything really, but offends me.
Still, we want to keep the actual update of the value from the site in "sync" with the running of the Lua script, so we don't want to just add an UpdateDivider=600 to the Calc measure or something, as that won't really tie the two (the WebParser and the Calc) together, just get them "close" as far as timing.
So, instead I used OnChangeAction in the Calc measure to run the !CommandMeasure bang. That way, the Lua script is only run when the value of the Calc measure is actually changed, which will only be when the WebParser measure goes out and gets a value from the web site that is different than what it was 10 minutes ago.
I set the initial state of the meter [MeterSP3] to Hidden=1, so it doesn't display invalid values before the WebParser measure has a chance to get the information from the web site. I use FinishAction=[!ShowMeter MeterSP3] on the WebParser measure to "unhide" the meter when the measure has finished getting and parsing the site.
Hope that makes sense. It's not a big deal, but it is the "right" way to do it.
-
- Posts: 1740
- Joined: November 13th, 2012, 9:53 pm
Re: thousands separator
Code: Select all
RegExpSubstitute=1
Substitute="\d{1,3}(?=(\d{3})+(?!\d))":"\0."
-
- Developer
- Posts: 22631
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: thousands separator
Yeah, I considered something like that, but it doesn't quite do all he wants. It will set the separator to "." and format that part of the number, but won't change the decimal place delimiter to ",". Now all of this might well be dependent on how he has his "locale" set up in Windows, and might be irrelevant, but I wanted something with maximum flexibility.moshi wrote:Code: Select all
RegExpSubstitute=1 Substitute="\d{1,3}(?=(\d{3})+(?!\d))":"\0."
Also, if the decimal places are more than three in length, like 123456789.1234 then it will format the decimal positions with the separator as well, "1.234.567.890.1.234". Not good.
I also like that the original string value of the WebParser measure stays unchanged, so it can be used (via the Calc measure with MinValue / MaxValue as in my example) as input to a Bar or Rotator meter later if desired.
Still, you might be able to get there with Regular Expression, but what would be the fun in that?
-
- Posts: 1740
- Joined: November 13th, 2012, 9:53 pm
Re: thousands separator
i'm drunk, but this should do it:
Code: Select all
[Variables]
Separator="."
Decimal=","
[Number]
Measure=Time
Format=10000000.1234567
RegExpSubstitute=1
Substitute="^(\d+)$":"\1A","([\.,])":"A","\d{1,3}(?=(\d{3})+A)":"\0B","A$":"","B":"#Separator#","A":"#Decimal#"
[Meter]
Meter=String
DynamicVariables=1
Text=Formatted: [Number]#CRLF#Unformatted: [Number:]
SolidColor=ffffff
-
- Developer
- Posts: 22631
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: thousands separator
Maybe, I'm too lazy to even attempt to figure that out.moshi wrote:i'm drunk, but this should do it:
Code: Select all
[Variables] Separator="." Decimal="," [Number] Measure=Time Format=10000000.1234567 RegExpSubstitute=1 Substitute="^(\d+)$":"\1A","([\.,])":"A","\d{1,3}(?=(\d{3})+A)":"\0B","A$":"","B":"#Separator#","A":"#Decimal#" [Meter] Meter=String DynamicVariables=1 Text=Formatted: [Number]#CRLF#Unformatted: [Number:] SolidColor=ffffff
-
- Posts: 40
- Joined: August 8th, 2013, 10:40 pm
Re: thousands separator
Hello,
thx for all the help, now it working fine.
Only two more errors to fix i think, and the Project is completed
All Ideas ar welcome
greeting Indy
thx for all the help, now it working fine.
Only two more errors to fix i think, and the Project is completed
All Ideas ar welcome
greeting Indy
You do not have the required permissions to view the files attached to this post.
-
- Developer
- Posts: 22631
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: thousands separator
I'd have to see the skin code and the .lua code you are using. I didn't have any GetStringValue() in the code I posted, so that one surprises me. The error from WebParser is a parsing error, but since you are getting the results you want, it might just be a problem with a second WebParser measure trying to use the result from an earlier one when it isn't "done" yet. So you get an initial error, but then on the next update it is corrected.