Excel VBA操作范围时出现类型不匹配错误。

huangapple go评论73阅读模式
英文:

Excel VBA working with ranges gets a Type Mismatch error

问题

我正在编写一个宏,它会循环遍历工作簿中的所有工作表。我需要获取从第11行到第30列开始的数据。每个工作表的最后一行都不同。

我尝试使用SQL和范围来获取每个工作表上所需的数据。获取数据后,我想将其粘贴到“数据”工作表上。在遍历所有工作表后,宏将执行一些其他操作。

我不经常使用SQL,而且我用过的几次数据始终都是从第1行/第1列开始的。这是我第一次尝试获取不是从第1行/第1列开始的数据。

当我运行宏时,我收到类型不匹配错误(在下面的代码中指示)。所有变量都已声明为公共变量。

英文:

I'm working on a macro that is cycling through all of the worksheets in a workbook. I need to grab data that starts on row 11 and goes to column 30. The last row on any given worksheet is different.

I'm trying to use SQL and Ranges to get the data I need on each worksheet. Once I get the data, I want to paste it on the "Data" worksheet. Once I go through all of the worksheets, the macro will do some other things.

I don't use SQL very often and the few times that I have my data has always started on row 1 / column 1. This is the first time I'm trying to grab data that does not start on row 1 / column 1.

When I run the macro, I'm getting a type mismatch error (indicated in the code below). All variables have been declared as public variables.

MyFileName = ""
MyFileName = ActiveWorkbook.Name

WrkShtCnt = 0
WrkShtCnt = Worksheets.Count
    
ws = 1
    
Do Until ws > WrkShtCnt
    
     DoEvents
        
     WrkShtName = ""
     WrkShtName = Trim(Workbooks(MyFileName).Worksheets(ws).Name)
        
     If UCase(WrkShtName) = "NOTES" Or UCase(WrkShtName) = "DATA" Then
          'skip as the macro will NOT be grabbing data from these 2 worksheets
     Else
          vStartDate = ""
          vStartDate = Format(Workbooks(MyFileName).Worksheets(ws).Cells(2, 1), "mm/dd/yyyy")
            
          vEndDate = ""
          vEndDate = Format(Workbooks(MyFileName).Worksheets(ws).Cells(3, 1), "mm/dd/yyyy")
            
          vExtra = ""
          vExtra = UCase(Trim(Workbooks(MyFileName).Worksheets(ws).Cells(4, 1)))
            
          vStr = ""
            
          If Len(vExtra) = 0 Then
               vStr = vStartDate & " - " & vEndDate
          Else
               vStr = vStartDate & " - " & vEndDate & " " & vExtra
          End If
                    
          vLastRow = 0
          vLastRow = Workbooks(MyFileName).Worksheets(ws).Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row
            
          MySheet = ""
          Set MySheet = Workbooks(MyFileName).Worksheets(ws)
            
          Set MyData = MySheet.Range(Workbooks(MyFileName).Worksheets(ws).Cells(11, 13), Worksheets(ws).Cells(vLastRow, 30))
            
          Dim dBcn As New ADODB.Connection
          Dim dbRS As New ADODB.Recordset

          dBConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & MyData & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
            
          dBcn.Open dBConn     
            
          vsql = ""
          vsql = "SELECT * FROM MyData"

          dbRS.Open vsql, dBcn   ' type mismatch error occurs on this line of code
            
            If FirstTime = True Then
               Workbooks(MyFileName).Worksheets("Data").Cells(2, 1).CopyFromRecordset dbRS
               FirstTime = False
            Else
                vLastRow = vLastRow + 1
                Workbooks(MyFileName).Worksheets("Data").Cells(vLastRow, 1).CopyFromRecordset dbRS
            End If
                       
            Set MyData = Nothing
            dbRS.Close
            dBcn.Close
        
        End If
        
        ws = ws + 1
        
   Loop

Some of the code is what I found while researching and I'm trying to adapt it to my situation.

Thanks in advance for any help or suggestions you provide that will can be past this roadblock. My endusers will thank you as well.....Thanks again.

答案1

得分: 1

以下是代码的部分,已被翻译成中文:

Option Explicit

Sub GetData()

    Dim wb As Workbook, ws As Worksheet, wsData As Worksheet
    Dim rngData As Range, LastRow As Long, r As Long
    
    Dim dbConn  As ADODB.Connection, sConn As String, rs As ADODB.Recordset
    Dim SQL As String
    Set dbConn = New ADODB.Connection
    
    ' 配置
    Set wb = ActiveWorkbook
    Set wsData = wb.Sheets("Data")
    wsData.UsedRange.Offset(1).ClearContents ' 保留标题
    
    ' 连接到工作簿
    sConn = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
            "Data Source=" & wb.FullName & _
            ";Extended Properties=""Excel 12.0 Macro;HDR=No;IMEX=1"";"
    'Debug.Print sConn
    dbConn.Open sConn
    
    ' 扫描每个工作表
    For Each ws In wb.Sheets
        If UCase(ws.Name) = "NOTES" Or ws.Name = wsData.Name Then
              ' 跳过,因为宏不会从这两个工作表中提取数据
        Else
                                    
            ' 数据范围
            LastRow = ws.UsedRange.Row + ws.UsedRange.Rows.Count - 1
            If LastRow < 11 Then
                 MsgBox "最后一行 < 11 = " & LastRow, vbCritical
                 Exit Sub
            Else
                 Set rngData = ws.Range("M11:AD" & LastRow)
            End If
            
            SQL = "SELECT * FROM [" & ws.Name & "$" & rngData.Address(0, 0) & "]"
            'Debug.Print SQL
            
            ' 复制记录
            Set rs = New ADODB.Recordset
            rs.Open SQL, dbConn, adOpenForwardOnly
            With wsData
               If r < 2 Then r = 2
               .Range("A" & r).CopyFromRecordset rs
               r = 1 + .Cells(.Rows.Count, "A").End(xlUp).Row
            End With
            
        End If
    Next
    dbConn.Close
    Set dbConn = Nothing
    MsgBox r - 2 & "条记录已复制到" & wsData.Name, vbInformation
End Sub
英文:

Use the address of the range in the SQL.

Option Explicit

Sub GetData()

    Dim wb As Workbook, ws As Worksheet, wsData As Worksheet
    Dim rngData As Range, LastRow As Long, r As Long
    
    Dim dbConn  As ADODB.Connection, sConn As String, rs As ADODB.Recordset
    Dim SQL As String
    Set dbConn = New ADODB.Connection
    
    &#39; config
    Set wb = ActiveWorkbook
    Set wsData = wb.Sheets(&quot;Data&quot;)
    wsData.UsedRange.Offset(1).ClearContents &#39; leave header
            
    &#39; connect to workbook
    sConn = &quot;Provider=Microsoft.ACE.OLEDB.12.0;&quot; &amp; _
            &quot;Data Source=&quot; &amp; wb.FullName &amp; _
            &quot;;Extended Properties=&quot;&quot;Excel 12.0 Macro;HDR=No;IMEX=1&quot;&quot;;&quot;
    &#39;Debug.Print sConn
    dbConn.Open sConn
   
    &#39; scan each sheets
    For Each ws In wb.Sheets
        If UCase(ws.Name) = &quot;NOTES&quot; Or ws.Name = wsData.Name Then
              &#39;skip as the macro will NOT be grabbing data from these 2 worksheets
        Else
                                    
            &#39; entent of data
            LastRow = ws.UsedRange.Row + ws.UsedRange.Rows.Count - 1
            If LastRow &lt; 11 Then
                 MsgBox &quot;Last row &lt; 11 = &quot; &amp; LastRow, vbCritical
                 Exit Sub
            Else
                 Set rngData = ws.Range(&quot;M11:AD&quot; &amp; LastRow)
            End If
            
            SQL = &quot;SELECT * FROM [&quot; &amp; ws.Name &amp; &quot;$&quot; &amp; rngData.Address(0, 0) &amp; &quot;]&quot;
            &#39;Debug.Print SQL
            
            &#39; copy records
            Set rs = New ADODB.Recordset
            rs.Open SQL, dbConn, adOpenForwardOnly
            With wsData
               If r &lt; 2 Then r = 2
               .Range(&quot;A&quot; &amp; r).CopyFromRecordset rs
               r = 1 + .Cells(.Rows.Count, &quot;A&quot;).End(xlUp).Row
            End With
            
        End If
    Next
    dbConn.Close
    Set dbConn = Nothing
    MsgBox r - 2 &amp; &quot; records copied to &quot; &amp; wsData.Name, vbInformation
End Sub

</details>



huangapple
  • 本文由 发表于 2023年5月21日 23:53:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76300742.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定