我有一张Excel表格,其中包含以下行:
1 | _Total | 0 C:
我已将单元格格式化为文本(可以重新格式化为任何内容)。即便如此,如果我必须使用匹配函数来匹配该行中的1
(如果它是application.match或application.worksheetfunction.match则无关紧要)我收到错误(类型不匹配错误)
disk_col = Application.WorksheetFunction.Match(disk_name, my_range, 0)
# disk_name : has to be a string, since I might need to match "_Total"
# my_range : it is the row
如果我match(CLng(disk_name), ....)
它会工作,但我不想使用CLng,因为我必须在某个时候匹配"_Total"
。
是否有类型无知的匹配功能?还是绕过这个?
编辑:现在,我已经创建了一个临时数组,其中行中的所有单元格都使用CStr()格式化为字符串,并使用数组上的匹配函数。将保留问题以获得更好的答案。
Edit2:添加了代码 -
Function get_property_value(disk_name As String, property_name As String, Optional counter_info As Variant) As Variant
Dim disk_col As Integer, property_row As Integer, last_row As Integer, last_col As Integer, all_devices As Variant, device_iter As Integer
disk_col = -1
property_row = -1
last_row = ActiveSheet.Cells(ActiveSheet.Rows.count, 1).End(xlUp).Row
last_col = ActiveSheet.Cells(1, ActiveSheet.Columns.count).End(xlToLeft).Column
' create array of all the cells in the row
ReDim all_devices(1 To last_col - 1)
For device_iter = 2 To last_col
all_devices(device_iter - 1) = CStr(Cells(1, device_iter).Text)
Next device_iter
' match the row and column
disk_col = Application.WorksheetFunction.Match(disk_name, all_devices, 0) + 1
property_row = Application.WorksheetFunction.Match(property_name, Range(Cells(2, 1), Cells(last_row, 1)), 0) + 1
If disk_col <> -1 And property_row <> -1 Then
get_property_value = Cells(property_row, disk_col).Value
Else
get_property_value = "Value not found."
End If
End Function
答案 0 :(得分:1)
如果您的行中包含的数据包含混合文本/数字,那么在1
与"1"
匹配时总是会出错,因为它们不相同。您可以使用工作表上的Match
函数对此进行测试。如果您的数据是字符串,并且输入=Match(1,...
,则会收到错误,反之亦然,如果您的数据是数字且输入=Match("1", ...
,则会收到错误。
对你的参数进行类型转换不会有帮助,因为它是范围内的值 - 而不是lookup_value
参数 - 这导致了这个,你需要转换行中的数据,这样它就是所有的字符串值。你通过强制转换到一个数组并匹配数组来完成这个。
或者,你可以做一些布尔检查。
首先:WorksheetFunction.Match
如果找不到匹配将失败,并且您的功能将无法正常返回。所以你需要使用Application.Match
。
然后,您需要将disk_col
和property_row
声明为Variant
,因为Match
可以返回错误值,如果您尝试将该结果放入Long/Integer
变量。
这应该让你开始:
Function get_property_value(disk_name As Variant, property_name As String, Optional counter_info As Variant) As Variant
Dim disk_col As Variant ' in case the value isn't found, you need to be able to contain the error.
Dim property_row As Variant ' same as above ^^
Dim last_row As Long
Dim last_col As Long
Dim device_iter As Long
Dim all_devices As Range
Set all_devices = Rows(1)
disk_col = -1
property_row = -1
If IsNumeric(disk_name) Then
disk_col = Application.Match(CLng(disk_name), all_devices, 0) + 1
Else
disk_col = Application.Match(CStr(disk_name), all_devices, 0) + 1
End If
With ActiveSheet
last_row = .Cells(.Rows.Count, 1).End(xlUp).Row
last_col = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
...
End Function