Unable to display unit symbol next to number in case of dicemal number using FormatValueOptions

Unable to display unit symbol next to number in case of dicemal number using FormatValueOptions

waleed.hany
Contributor Contributor
1,662 Views
6 Replies
Message 1 of 7

Unable to display unit symbol next to number in case of dicemal number using FormatValueOptions

waleed.hany
Contributor
Contributor

I am trying to create a user interface where a user can insert thickness.
I want to display the unit next to the text (which is converted from double). 
The approach I used is as follows:

ForgeTypeId LengthUnit = SpecTypeId.Length;
var formatOpt = Doc.GetUnits().GetFormatOptions(LengthUnit);
ForgeTypeId unitType = formatOptions.GetUnitTypeId();
FormatValueOptions formateValueOptions = new FormatValueOptions();
formateValueOptions.AppendUnitSymbol = true;
string formatedValue = UnitFormatUtils.Format(Doc.GetUnits(), LengthUnitType, d, true, formateValueOptions);

The issue is that it works while the number is non-decimal number, ex:    12 mm
while the unit symbol dissapears when the number has decimal unit ex:   12.2 

Is there a way I can make it work for all decimals ang numericals?
Thanks



0 Likes
Accepted solutions (1)
1,663 Views
6 Replies
Replies (6)
Message 2 of 7

RPTHOMAS108
Mentor
Mentor
Accepted solution

Not sure what you mean by that?

 

Private Function Obj_210814b(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData,
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result
   Dim UIDoc As UIDocument = commandData.Application.ActiveUIDocument
   If UIDoc Is Nothing Then Return Result.Cancelled Else
   Dim IntDoc As Document = UIDoc.Document

   Dim val As Double = 12.2 / 304.8

   Dim formateValueOptions As New FormatValueOptions
   formateValueOptions.AppendUnitSymbol = True
   Dim Unts As Units = IntDoc.GetUnits
   Dim Ops As FormatOptions = Unts.GetFormatOptions(SpecTypeId.Length)
   Ops.UseDefault = False
   Ops.Accuracy = 0.01
   Ops.SetUnitTypeId(UnitTypeId.Millimeters)
   Ops.SetSymbolTypeId(SymbolTypeId.Mm)
   formateValueOptions.SetFormatOptions(Ops)

   Debug.WriteLine(UnitFormatUtils.Format(Unts, SpecTypeId.Length, val, True, formateValueOptions))

   Ops.Accuracy = 1
   formateValueOptions.SetFormatOptions(Ops)

   Debug.WriteLine(UnitFormatUtils.Format(Unts, SpecTypeId.Length, val, True, formateValueOptions))

   Return Result.Succeeded
End Function

 

Output:

 

12.20 mm
12 mm

 

They need to address capitalisation of Mm since that representation is for a megametre not a millimetre.

 

Message 3 of 7

atis.sed
Advocate
Advocate

Hi, 

I have similar problem, but for some reason I cannot get the same results when following @RPTHOMAS108 solution: 

 double total_thickness_in = 12.2 / 304.8;
 FormatOptions FO = new FormatOptions();
FO.UseDefault = false;
FO.Accuracy = 0.0001;
FO.SuppressTrailingZeros = true;
FormatValueOptions format = new FormatValueOptions();
format.SetFormatOptions(FO);
string total_thickness_mm = UnitFormatUtils.Format(doc.GetUnits(), SpecTypeId.Length, total_thickness_in, true, format);

The output is:

0.0122

expected: 12.20

I don't want to set SetUnitTypeID to Milimeters as I want to use default units set in document:

 

atissed_0-1667848146773.png

 

 

0 Likes
Message 4 of 7

RPTHOMAS108
Mentor
Mentor

You are converting 12.2mm to ft (internal units for length) in the sense that you are dividing 12.2 by 304.8.

 

In terms of output you are getting what you are asking for i.e. 0.0122m is 12.2mm

 

Also from above image your current document units for length are mm and the square brackets indicate the symbol isn't set.

 

I think your main error is that you are not getting the format options i.e. after you get the units from the document (defaults) you should get the format options from the units (not create new format options). 

 

Unts.GetFormatOptions(SpecTypeId.Length)

 

If I were writing the above again, I would get rid of lines related to FormatValueOptions. You can do most of what you want with Units and FormatOptions i.e. I believe that if you change the FormatOptions of the input units then you don't really need to use the overload with the FormatValueOptions.

 

FormatValueOptions contains AppendUnitSymbol which overrides what is in the FormatOptions (it is false by default meaning use FormatOptions).

0 Likes
Message 5 of 7

atis.sed
Advocate
Advocate

Hi, 

I am converting 12.2mm to ft just for testing purposes, because Revits internal units are in ft. 

Then I am using FormatValueOptions to set rounding to 0.1 for this Method. Because although rounding is set to 0 in my Document, I want to change that to 0.1 .

In my final Method I get value from Wall layer thickness which is let's say 152.4mm but is rounded to 152mm.  So I want to change Accuracy by setting custom FormatValueOptions. But setting Accuracy just to 0.1 gives me output of 0.2mm instead of 152.4mm which is very strange...

 

0 Likes
Message 6 of 7

RPTHOMAS108
Mentor
Mentor

152.4 is half a ft so your input into the function should be 0.5. There is no reason to consider it being 152.4 you are just taking the value in internal units from the wall layer of 0.5 and feeding that into the function. The output is then in whatever units are used in the FormatOptions.

 

Depending on midpoint rounding 0.1524 rounded to 0.1 is 0.2 (it seems your output units are likely still in m for some reason). 

 

0) Get units from document Document.GetUnits

1) Get the format options from the Units Units.GetFormatOptions(SpecTypeId)

2) Change the unit format options

3) Put the changed unit FormatOptions back: Units.SetFormatOptions(ForgeTypeId, FormatOptions)

4) Use UnitFormatUtils(Units, ForgeTypeId, Double, Boolean)

 

or

 

0) Get units from document Document.GetUnits

1) Get the format options from the Units Units.GetFormatOptions(SpecTypeId)

2) Change the unit format options

3) Put the changed unit FormatOptions back: FormatValueOptions.SetFormatOptions(FormatOptions)

4) Use UnitFormatUtils(Units, ForgeTypeId, Double, Boolean, FormatValueOptions)

 

You've not fully done either of these processes above, the thing you haven't done is the thing I underlined above.

 

When you use 'new FormatOptions' consider the defaults as not being taken from the document, there is no argument for document so how can it know which document you are dealing with? It doesn't even know which spec it is formatting unless you provide that similar to below but again how the units in that relate to units in a document when it is created in isolation is vague (so I wouldn't use it).

 

Refer also to the difference between:

New FormatOptions

New FormatOptions(ForgeTypeId)

Noted in RevitAPI.chm

 

The majority of the time you want to just format units the way that they are formatted for the user in the UI. So you pass the Units from the Document into the function without change. Doing something else often requires reinventing the UI of the unit formatting settings. For example, what if your user is using Imperial not Metric are you going to then allow them to decide between ft/inches/ft and fractional inches with settings for all the rounded fractions etc. Are you going to invent an alternative unit settings interface for all of that or just avoid people that use that in North America? By dealing with units independently you are kind of building in cultural limitations.

 

However, a classic issue for me is that level elevations should be in m but if the default for length is mm I need to do something special because there is no distinction between Elevation and Length in the unit system. The metric level head magically deals with this contradiction: it has a label that displays the Elevation in m even though there is nothing to suggest it should do that (since spec for Elevation parameter is length which is in mm).

 

Cases like that is what I would use it for.

 

Message 7 of 7

atis.sed
Advocate
Advocate

Thank you!

Great point. Just have to stick with document settings. 


@RPTHOMAS108 wrote:

The majority of the time you want to just format units the way that they are formatted for the user in the UI. So you pass the Units from the Document into the function without change. Doing something else often requires reinventing the UI of the unit formatting settings. For example, what if your user is using Imperial not Metric are you going to then allow them to decide between ft/inches/ft and fractional inches with settings for all the rounded fractions etc. Are you going to invent an alternative unit settings interface for all of that or just avoid people that use that in North America? By dealing with units independently you are kind of building in cultural limitations.


0 Likes