I am building an Excel Addin using Visual Studio and am having trouble translating my VBA code that works as an Excel macro to VB.Net code. One item I am stuck on is how to run a macro on a range of data that has different values without returning a vb.null error message. Is there a way to run the below code for numbers in a range that include two of the below number formats? I tried to make the logic so that if it returns a Null value (because of 2 number formats in a range), it skips to the final Else statement and makes all values #,##0.0_);(#,##0.0). Thank you!
Private Sub BtnNumberFormat_Click(sender As Object, e As RibbonControlEventArgs) Handles BtnNumberFormat.Click
Dim ActiveWorksheet As Microsoft.Office.Interop.Excel.Worksheet =
Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1)
Dim Worksheet As Microsoft.Office.Tools.Excel.Worksheet =
Globals.Factory.GetVstoObject(ActiveWorksheet)
Dim Selection As Excel.Range = TryCast(Globals.ThisAddIn.Application.Selection, Excel.Range)
If Selection IsNot Nothing Then
****If Not IsDBNull(Selection) Then****
If Selection.NumberFormat = "#,##0.0_);(#,##0.0)" Then
Selection.NumberFormat = "$#,##0.0_);($#,##0.0)"
Else
If Selection.NumberFormat = "$#,##0.0_);($#,##0.0)" Then
Selection.NumberFormat = "#,##0.0%_);(#,##0.0%)"
Else
If Selection.NumberFormat = "#,##0.0%_);(#,##0.0%)" Then
Selection.NumberFormat = "#,##0.0x_)"
Else
If Selection.NumberFormat = "#,##0.0x_)" Then
Selection.NumberFormat = "General"
Else
Selection.NumberFormat = "#,##0.0_);(#,##0.0)"
End If
End If
End If
End If
****Else
Selection.NumberFormat = "#,##0.0_);(#,##0.0)"****
End If
End If
End Sub
First some background information.
From the documentation for the Excel.Range.NumberFormat Property :
Returns or sets a Variant value that represents the format code for the object.
Remarks
This property returns Null if all cells in the specified range don't have the same number format.
COM Variant Types can contain multiple sub-types and are marshaled to the .Net type System.Object
.
From Marshaling Variant to Object
When marshaling a variant to an object, the type, and sometimes the value, of the marshaled variant determines the type of object produced. The following table identifies each variant type and the corresponding object type that the marshaler creates when a variant is passed from COM to the .NET Framework.
Partial Listing from above reference:
COM variant type Object type ---------------- --------------- VT_EMPTY Null object reference (Nothing in Visual Basic). VT_NULL System.DBNull VT_DISPATCH System.__ComObject or null if (pdispVal == null) VT_UNKNOWN System.__ComObject or null if (punkVal == null) VT_ERROR System.UInt32 VT_BOOL System.Boolean VT_I1 System.SByte VT_UI1 System.Byte VT_I2 System.Int16 VT_UI2 System.UInt16
Since the Excel.Range.NumberFormat Property
returns a Variant null (VT_Null) when the Range contains multiple formats, .Net will receive a System.DBNull
object. Your posted code implies that you are aware of this, however the code is checking if the Excel.Range
object is a DBNull
and not the Excel.Range.NumberFormat
Property.
So instead of:
If Not IsDBNull(Selection) Then
use:
If Not IsDBNull(Selection.NumberFormat) Then
Your code is also using implicit type casting that can lead to many debugging problems. I strongly recommend that you enable Option Strict as it will force you to think about the variable types you are using and your code will run quicker as well.
If you instead declared a variable like this:
Dim numberFormat As String = TryCast(Selection.NumberFormat, String)
then the conditional logic would be:
If numberFormat Is Nothing Then
' multiple formats exist in range
Else
' check numberFormat
End If
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.