[翻译]  VBA Handling multiple custom datatype possibilities

[CHINESE]  VBA处理多种自定义数据类型的可能性


I have done some research and haven't found any similar question.

我做了一些研究,没有发现任何类似的问题。

I have a VBA macro that imports a .CSV file containing telegrams sent by a device.

我有一个VBA宏导入包含设备发送的电报的.CSV文件。

In the end of this macro, I want to create a graph with the time elapsed on the x-axis and the value corresponding to the telegram.

在这个宏的最后,我想创建一个图表,其中包含x轴上经过的时间和与电报相对应的值。

The issue is that this value can be of different types: hexadecimal, boolean, integer... And that they don't respect the standard Excel number format, which means that they can't be used to create a graph. Here are some examples (with " around the value to show its start and end) :

问题是这个值可以是不同的类型:十六进制,布尔值,整数......并且它们不尊重标准的Excel数字格式,这意味着它们不能用于创建图形。以下是一些示例(“显示其开始和结束的值”):

  • hexadecimal : "A7 C8"
  • 十六进制:“A7 C8”
  • Boolean : "$00" or ""$01"
  • 布尔值:“$ 00”或“”$ 01“
  • Percentage : "$30"
  • 百分比:“30美元”

And here is an example of data, with custom time format and boolean value

这是一个数据示例,具有自定义时间格式和布尔值

Here is my related code so far, where I try to convert into a custom type then convert back to numeric to get a common number datatype :

这是我到目前为止的相关代码,我尝试转换为自定义类型,然后转换回数字以获取公共数字数据类型:

If wsRes.Range("R1").Value Like "$##" Then
    wsRes.Range("R1:R" & plotLine).NumberFormat = "$##"
    wsRes.Range("R1:R" & plotLine).NumberFormat = General
End If

If wsRes.Range("R1").Value Like "??[ ]??" Then
    Dim valArray(1) As String
    For i = 1 To plotLine Step 1
        valArray = Split(wsRes.Range("R" & i), " ")
        wsRes.Range("R" & i).Value = ToInt32(valArray(0) + valArray(1), 16)
        wsRes.Range("" & i).NumberFormat = General
    Next i
End If

I haven't been able to test it with hexa yet, but the conversion trick doesn't work with percentage/boolean

我还没能用hexa测试它,但转换技巧不适用于百分比/布尔值

EDIT :

编辑:

First, thank you for your answers.

首先,谢谢你的答案。

Here is my final code for anyone's interested, adapted from Vityata's.

这是我最后的代码,任何人都感兴趣,改编自Vityata的。

This method will allow to easily add other datatypes if needed.

如果需要,此方法将允许轻松添加其他数据类型。

Sub TestMe()
    Dim RangeData as String
    Set wsRes = ActiveWorkbook.Sheets("Results")

    For i = 1 To plotLine Step 1  'plotLine is the last line on which I have data
        DetectType wsRes.Range("R" & i).Value, i
    Next i

    RangeData = "Q1:R" & plotLine
    CreateGraph RangeData 'Call My sub creating the graph
End Sub



Public Sub DetectType(str As String, i As Integer)

    Select Case True
        Case wsRes.Range("R" & i).Value Like "??[ ]??"
            wsRes.Range("R" & i).Value = HexValue(str)

        Case wsRes.Range("R" & i).Value Like "?##"
            wsRes.Range("R" & i).Value = DecValue(str)

        Case Else
            MsgBox "Unsupported datatype detected : " & str
            End
    End Select

End Sub



Public Function HexValue(str As String) As Long
    Dim valArray(1) As String 'Needed as I have a space in the middle that prevents direct conversion
    valArray(0) = Split(str, " ")(0)
    valArray(1) = Split(str, " ")(1)
    HexValue = CLng("&H" & valArray(0) + valArray(1))
End Function


Public Function DecValue(str As String) As Long
    DecValue = Right(str, 2)
End Function

1 个解决方案

#1


6  

You need three boolean functions, following your business logic and some of the Clean Code principles (although the author of the book does not recognize VBA people as programmers):

您需要三个布尔函数,遵循您的业务逻辑和一些清洁代码原则(尽管本书的作者不承认VBA人员是程序员):

  • IsHex()
  • IsHex()
  • IsBoolean()
  • IsBoolean()
  • IsPercentage()
  • IsPercentage()

Public Sub TestMe()

    Dim myInput As Variant
    myInput = Array("A7C8", "$01", "$30")        
    Dim i As Long        
    For i = LBound(myInput) To UBound(myInput)
        Debug.Print IsHex(myInput(i))
        Debug.Print IsBoolean(myInput(i))
        Debug.Print IsPercentage(myInput(i))
        Debug.Print "-------------"
    Next i        
    'or use this with the DetectType() function below:
    'For i = LBound(myInput) To UBound(myInput)
    '    Debug.Print DetectType(myInput(i))
    'Next i

End Sub

Public Function IsHex(ByVal str As String) As Boolean    
    On Error GoTo IsHex_Error       
    IsHex = (WorksheetFunction.Hex2Dec(str) <> vbNullString)        
    On Error GoTo 0
    Exit Function    
IsHex_Error:    
End Function

Public Function IsBoolean(ByVal str As String) As Boolean
    IsBoolean = CBool((str = "$00") Or (str = "$01"))
End Function

Public Function IsPercentage(ByVal str As String) As Boolean
    IsPercentage = (Len(str) = 3 And Left(str, 1) = "$" And IsNumeric(Right(str, 2)))
End Function

Then some additional logic is needed, because $01 is both Boolean and Percentage. In this case, you can consider it Percentage. This is some kind of a mapper, following this business logic:

然后需要一些额外的逻辑,因为$ 01既是布尔值也是百分比。在这种情况下,您可以将其视为百分比。这是一种映射器,遵循以下业务逻辑:

Public Function DetectType(str) As String

    Select Case True
        Case IsHex(str)
            DetectType = "HEX!"
        Case IsPercentage(str) And IsBoolean(str)
            DetectType = "Boolean!"
        Case IsPercentage(str)
            DetectType = "Percentage!"
        Case Else
            DetectType = "ELSE!"
    End Select

End Function

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2018 ITdaan.com 粤ICP备14056181号