简体   繁体   English

循环遍历行,当为空时移动到下一列 - vba

[英]Loop through rows and when empty move to next column - vba

I've been spending days in trying to figure out how I need to do this but just can't find it.我花了几天时间试图弄清楚我需要如何做到这一点,但就是找不到。 Hope some one is kind enough to help me out.希望有人能帮助我。 The goal of this script is to get a table from a website and put them in a table in Excel.此脚本的目标是从网站获取一个表并将它们放入 Excel 的表中。

But I need 6 (For the time being. In the future this will be more than 26 different tables) different tables and I don't want to make a sub for each table request.但我需要 6 个(暂时。将来这将是超过 26 个不同的表)不同的表,我不想为每个表请求创建一个子表。 So I put all the variable data on Sheet1 of my file.所以我把所有的变量数据放在我文件的 Sheet1 上。

在此处输入图像描述

The idea is that my script goes over each column and gets the table that I need until there is an empty column.这个想法是我的脚本遍历每一列并获取我需要的表,直到有一个空列。 To get this data for 1 column isn't an issue as this is working.获取 1 列的此数据不是问题,因为这是有效的。 The issue is that I just can't figure out how I can move on to column B, column C, ... until there is an empty column.问题是我只是不知道如何移动到 B 列,C 列,......直到有一个空列。

I've been trying every single thing that I found online, but nothing seem to get it going.我一直在尝试我在网上找到的每一件事,但似乎没有任何进展。 If somebody can help me out or give me clear pointers how to do that would be very much appreciated.如果有人可以帮助我或给我明确的指示如何做到这一点,将不胜感激。

Sub ImportTBL1()
    
    Dim sourceSheet As Worksheet
    Dim QT As QueryTable
    Dim destCell As Range
    Dim qtResultRange As Range
    Dim TBL As String
    Dim URL As String
    Dim DES As String
    Dim COL As String
    
    Set sourceSheet = Sheet6
    Dim rng As Range: Set rng = Application.Range("Sheet1!A1")
    Dim cel As Range
        
        For Each cel In rng.Cells
            TBL = rng.Cells(1)
            URL = rng.Cells(2)
            DES = rng.Cells(3)
            COL = rng.Cells(4)
        Next cel
         
    With sourceSheet
        Set destCell = .Range(DES)
        On Error Resume Next
        .ListObjects(TBL).Delete
        On Error GoTo 0
    End With
    
    Set QT = destCell.Worksheet.QueryTables.Add(Connection:="URL;" & URL, Destination:=destCell)
    
    With QT
        .RefreshStyle = xlOverwriteCells
        .WebFormatting = xlNone
        .WebSelectionType = xlSpecifiedTables
        .WebTables = COL
        .BackgroundQuery = False
        .Refresh
        Set qtResultRange = .ResultRange
        .Delete
    End With
    
    With destCell
        .Worksheet.ListObjects.Add(xlSrcRange, .CurrentRegion, , xlYes).Name = TBL
        sourceSheet.ListObjects(TBL).ShowAutoFilterDropDown = False
    End With

End Sub

You did not answer the clarification question, but looking at your code I (only suppose) that your code needs only the first 5 rows of each column to be processed.您没有回答澄清问题,但查看您的代码我(仅假设)您的代码只需要处理每列的前 5 行。 At least, the following code is based on the above described assumption.至少,下面的代码是基于上述假设的。 Please, test it and send some feedback:请测试它并发送一些反馈:

Sub ImportTBL1()
    Dim sourceSheet As Worksheet, QT As QueryTable, destCell As Range
    Dim qtResultRange As Range, TBL As String, URL As String
    Dim DES As String, COL As String, colsNo As Long, i As Long
    
    Set sourceSheet = Sheet6: colsNo = 6 'use here the number of columns to be processed
    Dim rng As Range, cel As Range
    
    For i = 1 To colsNo
        Set rng = Sheet1.cells(1, i).Value
            
            For Each cel In rng.cells
                TBL = rng.cells(1)
                URL = rng.cells(2)
                DES = rng.cells(3)
                COL = rng.cells(4)
            Next cel
             
        With sourceSheet
            Set destCell = .Range(DES)
            On Error Resume Next
            .ListObjects(TBL).Delete
            On Error GoTo 0
        End With
        
        Set QT = destCell.Worksheet.QueryTables.Add(Connection:="URL;" & URL, Destination:=destCell)
        
        With QT
            .RefreshStyle = xlOverwriteCells
            .WebFormatting = xlNone
            .WebSelectionType = xlSpecifiedTables
            .WebTables = COL
            .BackgroundQuery = False
            .Refresh
            Set qtResultRange = .ResultRange
            .Delete
        End With
        
        With destCell
            .Worksheet.ListObjects.Add(xlSrcRange, .CurrentRegion, , xlYes).Name = TBL
            sourceSheet.ListObjects(TBL).ShowAutoFilterDropDown = False
        End With
    Next i
End Sub

I will just add some context around @FaneDuru's answer and to also help the OP with some understanding about how to approach the problem.我将围绕@FaneDuru 的答案添加一些上下文,并帮助 OP 了解如何解决问题。

Essentially all you need to do is wrap your code in a For loop - as you have a specific task that you want to repeat across independent columns.基本上你需要做的就是将你的代码包装在一个For循环中——因为你有一个特定的任务要在独立的列中重复。

In VBA, you have the option of either using a For Each loop or a For Next loop.在 VBA 中,您可以选择使用For Each循环或For Next循环。 Each has their benefits and use and I suppose each could be used in this case.每个都有其优点和用途,我想每个都可以在这种情况下使用。 That being said, I would prefer the For Next loop because that would mean I no longer need a Range object to loop through using the For Each approach.话虽如此,我更喜欢For Next循环,因为这意味着我不再需要Range object 来循环使用For Each方法。

Approach 1: For Next方法一:为下一个

Sub ImportTBL1()

    Dim sourceSheet As Worksheet, QT As QueryTable, destCell As Range
    Dim qtResultRange As Range, TBL As String, URL As String
    Dim DES As String, COL As String
    Dim iCols As Long
    
    Set sourceSheet = Sheet6
    iCols = Sheets("Sheet1").Range("A1").End(xlToRight).Column
    
    For i = 1 To iCols

        TBL = Sheets("Sheet1").Cells(1,i).Value
        URL = Sheets("Sheet1").Cells(2,i).Value
        DES = Sheets("Sheet1").Cells(3,i).Value
        COL = Sheets("Sheet1").Cells(4,i).Value
             
        With sourceSheet
            Set destCell = .Range(DES)
            On Error Resume Next
            .ListObjects(TBL).Delete
            On Error GoTo 0
        End With
        
        Set QT = destCell.Worksheet.QueryTables.Add(Connection:="URL;" & URL, Destination:=destCell)
        
        With QT
            .RefreshStyle = xlOverwriteCells
            .WebFormatting = xlNone
            .WebSelectionType = xlSpecifiedTables
            .WebTables = COL
            .BackgroundQuery = False
            .Refresh
            Set qtResultRange = .ResultRange
            .Delete
        End With
        
        With destCell
            .Worksheet.ListObjects.Add(xlSrcRange, .CurrentRegion, , xlYes).Name = TBL
            sourceSheet.ListObjects(TBL).ShowAutoFilterDropDown = False
        End With
    Next i
End Sub

Approach 2: For Each方法 2:对于每个

Sub ImportTBL1()

    Dim sourceSheet As Worksheet, QT As QueryTable, destCell As Range
    Dim qtResultRange As Range, TBL As String, URL As String
    Dim DES As String, COL As String
    Dim iCols As Long
    
    Set sourceSheet = Sheet6
    iCols = Sheets("Sheet1").Range("A1").End(xlToRight).Column
    Dim rng As Range: cel As Range
    
    With Sheets("Sheet1")
        Set rng = .Range(.Cells(1, 1), .Cells(1,iCols))
    End With

    For Each cel in rng
        
        TBL = cel.Value
        URL = cel.Offset(1,0).Value
        DES = cel.Offset(2,0).Value
        COL = cel.Offset(3,0).Value

        With sourceSheet
            Set destCell = .Range(DES)
            On Error Resume Next
            .ListObjects(TBL).Delete
            On Error GoTo 0
        End With
        
        Set QT = destCell.Worksheet.QueryTables.Add(Connection:="URL;" & URL, Destination:=destCell)
        
        With QT
            .RefreshStyle = xlOverwriteCells
            .WebFormatting = xlNone
            .WebSelectionType = xlSpecifiedTables
            .WebTables = COL
            .BackgroundQuery = False
            .Refresh
            Set qtResultRange = .ResultRange
            .Delete
        End With
        
        With destCell
            .Worksheet.ListObjects.Add(xlSrcRange, .CurrentRegion, , xlYes).Name = TBL
            sourceSheet.ListObjects(TBL).ShowAutoFilterDropDown = False
        End With
    Next cel
End Sub

I have not tested either of the above but you should hopefully get the picture.我没有测试过上述任何一个,但你应该希望能得到图片。 I will leave it up to you to do further research as to each approach.我将留给您对每种方法进行进一步的研究。

I have found it.我找到了。 Finally.最后。

Here's the working script.这是工作脚本。 Maybe someone can use it in the future.也许将来有人可以使用它。 Thank you all for the help.谢谢大家的帮助。

    Sub ImportTBL1()
   
    Dim sourceSheet As Worksheet
    Dim QT As QueryTable
    Dim destCell As Range
    Dim qtResultRange As Range
    Dim TBL As String
    Dim URL As String
    Dim DES As String
    Dim COL As String
   
    Set sourceSheet = Sheet6
    Dim rng As Range:
    
    'Loop through each used cell in row 1
    For Each rng In Sheets("Sheet1").Range("A1", Sheets("Sheet1").Cells(1, Columns.Count).End(xlToLeft))
    'Dim cel As Range
       
        'For Each cel In rng.Cells   'rng is only one cell. No need to loop through one cell
            TBL = rng.Cells(1, 1)
            URL = rng.Cells(2, 1)
            DES = rng.Cells(3, 1)
            COL = rng.Cells(4, 1)
        'Next cel
             
         With sourceSheet
             Set destCell = .Range(DES)
             On Error Resume Next
             .ListObjects(TBL).Delete
             On Error GoTo 0
         End With
        
         Set QT = destCell.Worksheet.QueryTables.Add(Connection:="URL;" & URL, Destination:=destCell)
        
         With QT
             .RefreshStyle = xlOverwriteCells
             .WebFormatting = xlNone
             .WebSelectionType = xlSpecifiedTables
             .WebTables = COL
             .BackgroundQuery = False
             .Refresh
             Set qtResultRange = .ResultRange
             .Delete
         End With
        
         With destCell
             .Worksheet.ListObjects.Add(xlSrcRange, .CurrentRegion, , xlYes).Name = TBL
             sourceSheet.ListObjects(TBL).ShowAutoFilterDropDown = False
         End With
         
    Next rng

End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM