VBA-范围对象在循环中仅设置一次

VBA-范围对象在循环中仅设置一次,vba,excel,range,Vba,Excel,Range,我正在编写匹配日期(来自文件)的代码,将其放入集合,然后尝试在电子表格中查找。一旦找到它,它会将以下两个项放在集合中的两个单元格中。当我运行此命令时,我得到以下错误:“对象变量或块变量未设置”。我试图调试我的代码,它显示在下面代码的第一个循环之后,range对象“rthecell”更改为正确的值。循环的第二次迭代发生后,“rthecell”的值变为“Nothing” 例: 同样,在循环的第一次迭代中,一切都按预期工作,但是一旦第二次迭代发生,我就会收到错误 以下是完整的代码: Sub Input

我正在编写匹配日期(来自文件)的代码,将其放入集合,然后尝试在电子表格中查找。一旦找到它,它会将以下两个项放在集合中的两个单元格中。当我运行此命令时,我得到以下错误:“对象变量或块变量未设置”。我试图调试我的代码,它显示在下面代码的第一个循环之后,range对象“rthecell”更改为正确的值。循环的第二次迭代发生后,“rthecell”的值变为“Nothing”

例:

同样,在循环的第一次迭代中,一切都按预期工作,但是一旦第二次迭代发生,我就会收到错误

以下是完整的代码:

Sub InputData()

'Declare variables

Dim sFilePath As String
Dim sLineFromFile As String
Dim saLineItems() As String
Dim element As Variant
Dim col As Collection
Dim LineItem1 As String
Dim LineItem2 As String
Dim LineItem3 As String
Dim rtheCell As Range

Set col = New Collection

'Insert file path name here, this file will be overwritten each morning

sFilePath = "P:\Billing_Count.csv"

Open sFilePath For Input As #1

Do Until EOF(1)

    Line Input #1, sLineFromFile

    'Split each line into a string array
    'First replace all space with comma, then replace all double comma with single comma
    'Replace all commas with space
    'Then perform split with all values separated by one space

    sLineFromFile = Replace(sLineFromFile, Chr(32), ",")
    sLineFromFile = Replace(sLineFromFile, ",,", ",")
    sLineFromFile = Replace(sLineFromFile, ",", " ")
    saLineItems = Split(sLineFromFile, " ")

    'Add line from saLineItem array to a collection
    For Each element In saLineItems
        If element <> " " Then
        col.Add element
        End If
    Next

Loop

Close #1

'Place each value of array into a smaller array of size 3
Dim i As Integer
i = 1

Do Until i > col.Count


    'Place each value of array into a string-type variable

    'This line is the date
    LineItem1 = col.Item(i)
    i = i + 1
    'This line should be the BW count make sure to check
    LineItem2 = col.Item(i)
    i = i + 1
    'This line should be the ECC count make sure to check
    LineItem3 = col.Item(i)
    i = i + 1

    'Find the matching date in existing Daily Billing File (dates on Excel must be formatted as
    'general or text) and add ECC and BW counts on adjacent fields

    Set rtheCell = Range("A3:A37").Find(What:=LineItem1)
    rtheCell.Offset(, 1).Value = LineItem3 'This is LineItem3 since we can ECC data to appear before BW
    rtheCell.Offset(, 2).Value = LineItem2
    Set rtheCell = Nothing
    LineItem1 = 0

Loop

'Format cells to appear as number with no decimals
'Format cells to have horizontal alignment
Sheets(1).Range("B3:C50").NumberFormat = "0"
Sheets(1).Range("C3:C50").HorizontalAlignment = xlRight


End Sub
子输入数据()
'声明变量
将sFilePath设置为字符串
将sLineFromFile设置为字符串
Dim saLineItems()作为字符串
作为变体的Dim元素
收藏
将LineItem1设置为字符串
将LineItem2设置为字符串
将LineItem3设置为字符串
变暗rtheCell As范围
Set col=新集合
'在此处插入文件路径名,此文件将在每天早上被覆盖
sFilePath=“P:\Billing\u Count.csv”
打开输入为#1的sFilePath
直到EOF(1)为止
行输入#1,sLineFromFile
'将每行拆分为字符串数组
'首先用逗号替换所有空格,然后用单逗号替换所有双逗号
'将所有逗号替换为空格
'然后执行拆分,所有值用一个空格分隔
sLineFromFile=Replace(sLineFromFile,Chr(32),“,”)
sLineFromFile=Replace(sLineFromFile,,,,,,,)
sLineFromFile=Replace(sLineFromFile,,,,)
saLineItems=Split(sLineFromFile,“”)
'将saLineItem数组中的行添加到集合
盐生元素中的每种元素
如果元素“”那么
添加元素
如果结束
下一个
环
关闭#1
'将数组的每个值放入大小为3的较小数组中
作为整数的Dim i
i=1
直到我数到上校为止
'将数组的每个值放入字符串类型变量中
“这行是日期
LineItem1=列项目(i)
i=i+1
'此行应为BW计数,请确保检查
LineItem2=列项目(i)
i=i+1
'此行应为ECC计数,请务必检查
LineItem3=列项目(i)
i=i+1
'在现有每日账单文件中查找匹配的日期(Excel上的日期必须格式化为
'常规或文本),并在相邻字段上添加ECC和BW计数
设置rtheCell=Range(“A3:A37”)。查找(What:=LineItem1)
rtheCell.Offset(,1).Value=LineItem3'这是LineItem3,因为我们可以将ECC数据显示在BW之前
rtheCell.Offset(,2).Value=LineItem2
设置rtheCell=Nothing
LineItem1=0
环
'将单元格格式化为不带小数的数字
'将单元格格式化为水平对齐
表(1).范围(“B3:C50”).NumberFormat=“0”
第(1)页。范围(“C3:C50”)。水平对齐=xlRight
端接头
使用时,通常会在后续调用中使用
After:=
参数,或者使用假定
After:=
为最后找到的项的。由于您没有以任何方式修改实际找到的单元格的值,因此需要记录原始找到的单元格(通常是地址),因为最终您将返回到原始单元格

dim fndrng as range, fndstr as string
set fndrng = Range("A:A").Find(What:=LineItem1, after:=cells(rows.count, "A"))
if not fndrng is nothing then
    fndstr = fndrng.address
    do while True

        'do stuff here

        set fndrng = Range("A:A").FindNext(after:=fndrng)
        if fndstr = fndrng.address then exit do
    loop
end if

这会让你产生循环所有匹配调用的想法,直到你循环回原始调用。tbh,很难对提供的少量代码进行充分扩展。

让我们看看整个循环LineItem1在第二个循环中是否发生了变化?如果找到了,我怀疑下一个项目根本就没有找到rhteCell@A.S.HLineItem1确实更改为正确的值。它基本上找不到下一个值,即使它在那里。如果找不到LineItem1,则
rtheCell
将为
Nothing
-您需要进行测试,这对我不起作用。我不明白为什么我使用的Find函数只查找第一条记录。例如,它将使rtheCell“20151203”并在工作表上找到它。下一次迭代无法找到“20151204”,尽管它确实存在于工作表中,并将rtheCell保留为“Nothing”。打开一个空白工作表,在几个随机单元格中键入abc。现在点击[cntll+F]并查找abc。你会先找到第一个,然后是第二个,依此类推,直到你重新找到第一个。这就是我上面所描述的,结果是在我提取的数据前面有一个换行符。使用这个和你的解决方案,我能够解决这个问题!谢谢
dim fndrng as range, fndstr as string
set fndrng = Range("A:A").Find(What:=LineItem1, after:=cells(rows.count, "A"))
if not fndrng is nothing then
    fndstr = fndrng.address
    do while True

        'do stuff here

        set fndrng = Range("A:A").FindNext(after:=fndrng)
        if fndstr = fndrng.address then exit do
    loop
end if