How would you calculate the number of pixels for a String (in an arbitrary font), using an Excel VBA macro?
Related:
To expand on and hone Dustin's answer, here is the code that I use.
Like Dustin, I have a label on a hidden user form with AutoSize = True
. Make sure WordWrap = False
or else you get bizarre results;)
However, there is a bit of extra fluff added onto the label's width each time. To correct for it, you need to also find the width of an blank caption and subtract the difference. Even that is problematic sometimes so in my code I find the difference between the string plus an arbitrary character and the arbitrary character by itself.
The following code can go in any module you like. frmTextWidth
is the name of the custom form and Label1
is the label that will measure the width of text.
Public Function TextWidth(ByVal Text As Variant, _
Optional ByVal FontName As Variant, _
Optional FontSize As Double) As Single
If TypeName(Text) = "Range" Then
If IsMissing(FontName) Then Set FontName = Text
Text = Text.Value
End If
If TypeName(FontName) = "Range" Then
frmTextWidth.Label1.Font = FontName.Font
ElseIf VarType(FontName) = vbString Then
If FontName <> "" Then frmTextWidth.Label1.Font.Name = FontName
If FontSize <> 0 Then frmTextWidth.Label1.Font.Size = FontSize
End If
frmTextWidth.Label1.Caption = CStr(Text) + "."
TextWidth = frmTextWidth.Label1.Width
frmTextWidth.Label1.Caption = "."
TextWidth = TextWidth - frmTextWidth.Label1.Width
End Function
You can supply a range as the string source and the function will automatically pick up the string and its font. If you have a string in a cell that has mixed fonts and font sizes, you can understand that this function won't work. You would have to find the size of each individual formated character but the code involved is not too tricky.
If you call the function allot, you may not want to set the font of the label every time because it will bog down the function. Simply test to see if the requested font name/size is different than what Label1
is set to before changing it.