【问题标题】:Proceed to next empty cell if a condition is met如果满足条件,则继续下一个空单元格
【发布时间】:2019-02-27 11:44:24
【问题描述】:

我在第一行有一张带有项目名称的工作表。

我正在使用Forloop 来通过第 1 行中的单元格 - i。 我使用每个单元格的值内容从第 2 行中相应单元格下方的 .CSV 文件中导入一列,为此使用 j。 但是,我有一些 .CSV 文件丢失了,我需要移动到第 2 行中的下一个单元格,同时移动到第 1 行中的下一个单元格。基本上跳过一列。

到目前为止我所拥有的是:

Dim FSO As Object
Dim Folder As Object
Dim File As String

Set FSO = CreateObject("Scripting.FileSystemObject")
Set Folder = FSO.GetFolder("C:\Users\Betty\AppData\Roaming\MetaQuotes\Terminal\B4D9BCD10BE9B5248AFCB2BE2411BA10\MQL4\Files")

For i = 2 To HCP.Cells(1, HCP.Columns.Count).End(xlToLeft).Column

Item = HCP.Cells(1, i).Value

FilePath = Folder & "\" & Item & "1440.CSV"

    If Item = "" Or Dir(FilePath) = "" Then GoTo Continue
        j = HCP.Cells(2, HCP.Columns.Count).End(xlToLeft).Column
            With HCP.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=HCP.Cells(2, j + 1))
                .TextFileParseType = xlDelimited
                .TextFileCommaDelimiter = True
                .TextFileSpaceDelimiter = True
                .TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
                .Refresh BackgroundQuery:=False
            End With

Continue:

Next 

我需要j 的列索引始终与i 的列索引相对应。

【问题讨论】:

    标签: vba for-loop if-statement conditional-statements


    【解决方案1】:

    解决方案2:嵌套Do循环

    避免使用“继续”命令,因为它不是 VBA 命令。

    For i = 2 To BS.Cells(1, BS.Columns.Count).End(xlToLeft).Column: Do
    
    Item = BS.Cells(1, i).Value
    FilePath = Folder & "\" & Item & "1440.CSV"
    
        If Item = "" Or Dir(FilePath) = "" Then Exit Do
            j = BS.Cells(2, BS.Columns.Count).End(xlToLeft).Column
                If j <> i Then j = i
                    With BS.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=BS.Cells(2, j))
                        .TextFileParseType = xlDelimited
                        .TextFileCommaDelimiter = True
                        .TextFileSpaceDelimiter = True
                        .TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
                        .Refresh BackgroundQuery:=False
                    End With
    
    Loop While False: Next i
    

    请注意For i 末尾的: Do

    如果以下条件一个,即Item = ""Dir(FilePath) = ""False,则退出Do循环。如果声明了 Do 循环的 Loop While False: Next i 条件,则为真。

    这两个条件也可以表示为:

    For i = 2 To BS.Cells(1, BS.Columns.Count).End(xlToLeft).Column: Do
    
    If Item <> "" Or Dir(FilePath) <> "" Then
    
       'Do something...
    
    Else: Exit Do
    
    End If
    
    Loop While True: Next i
    

    If Item = "" Or Dir(FilePath) = "" Then Exit Do 中的Or 条件是强制性的,因为i 可能是Value &lt;&gt; " ",但文件中的FilePath 可能不存在,即Dir(FilePath) = " ",这将引发错误和以前一样。

    在这种情况下If j &lt;&gt; i Then j = i 是强制性的,因为For i 表示为=2 To,这意味着循环从第2 列开始。

    这可以通过将For i 循环声明为For i = 1 To 来避免。然而,这是完成工作的初始循环。

    进一步j可以表述为j = BS.Cells(2, i),得到i的值作为列索引。

    但是,为了进一步的保证目的,建议使用If j &lt;&gt; i Then j = i 声明。

    在进一步的搜索中出现了更多的解决方案。

    请参阅解决方案 3:嵌套 For 循环和嵌套 If 语句

    【讨论】:

      【解决方案2】:

      解决方案 3:嵌套 ForLoop 和嵌套 IfStatement

      For i = 1 To BS.Cells(1, BS.Columns.Count).End(xlToLeft).Column
      
          For j = 1 To BS.Cells(2, BS.Columns.Count - 1).End(xlToLeft).Column
      
              Item = BS.Cells(1, i).Value
              FilePath = Folder & "\" & Item & "1440.CSV"
      
                  If ((Item <> "") Or (Dir(FilePath) <> "") And (i = j)) Then
      
                       With BS.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=BS.Cells(2, j + 1))
                           .TextFileParseType = xlDelimited
                           .TextFileCommaDelimiter = True
                           .TextFileSpaceDelimiter = True
                           .TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
                           .Refresh BackgroundQuery:=False
                       End With
      
                  End If
      
           Next j
      
      Next i
      

      【讨论】:

        【解决方案3】:

        我会避免使用GoTo Continue。只需在进入循环之前检查您的陈述是否定的。您的问题和解决方案中还缺少一些 End If 声明。

        如果ItemDir 为空白,我让cmets 显示代码将跳转到的位置。结果相同,只是代码更简洁。

        For i = 2 To HCP.Cells(1, HCP.Columns.Count).End(xlToLeft).Column
        
        Item = HCP.Cells(1, i).Value
        FilePath = Folder & "\" & Item & "1440.CSV"
        
            If Item <> "" Or Dir(FilePath) <> "" Then 'Test Here
                j = HCP.Cells(2, HCP.Columns.Count).End(xlToLeft).Column
                    If j <> i Then j = i
                        With HCP.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=HCP.Cells(2, j))
                            .TextFileParseType = xlDelimited
                            .TextFileCommaDelimiter = True
                            .TextFileSpaceDelimiter = True
                            .TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
                            .Refresh BackgroundQuery:=False
                        End With
            End If 'Skips to here if either are blank.
        Next i
        

        【讨论】:

        • 感谢@urdearboy 纠正和改进我的代码。 +1
        • 但是,我在第二个 End If 上收到“编译错误:没有块 If 的 End If”。 @urdearboy
        • 更新了@I.Я.Newb 对此感到抱歉
        • 条件应该是If Item &lt;&gt; "" And Dir(FilePath) &lt;&gt; "" Then 'Test Here,用And,而不是Or
        • 随时接受您的解决方案之一作为答案! :)
        【解决方案4】:

        我想通了。这就是我现在使用的。

        For i = 2 To HCP.Cells(1, HCP.Columns.Count).End(xlToLeft).Column
        
        Item = HCP.Cells(1, i).Value
        FilePath = Folder & "\" & Item & "1440.CSV"
        
            If Item = "" Or Dir(FilePath) = "" Then GoTo Continue
                j = HCP.Cells(2, HCP.Columns.Count).End(xlToLeft).Column
                    If j <> i Then j = i
                        With HCP.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=HCP.Cells(2, j))
                            .TextFileParseType = xlDelimited
                            .TextFileCommaDelimiter = True
                            .TextFileSpaceDelimiter = True
                            .TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
                            .Refresh BackgroundQuery:=False
                        End With
        
        Continue:
        
        Next
        

        结果如下:

        请随时提出任何其他建议。

        【讨论】:

        • 在上面的例子中,Continue 命令可以替换为Next Iteration,因为Continue 命令是一个非VBA 命令。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多