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

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

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.

  1. MyFileName = ""
  2. MyFileName = ActiveWorkbook.Name
  3. WrkShtCnt = 0
  4. WrkShtCnt = Worksheets.Count
  5. ws = 1
  6. Do Until ws > WrkShtCnt
  7. DoEvents
  8. WrkShtName = ""
  9. WrkShtName = Trim(Workbooks(MyFileName).Worksheets(ws).Name)
  10. If UCase(WrkShtName) = "NOTES" Or UCase(WrkShtName) = "DATA" Then
  11. 'skip as the macro will NOT be grabbing data from these 2 worksheets
  12. Else
  13. vStartDate = ""
  14. vStartDate = Format(Workbooks(MyFileName).Worksheets(ws).Cells(2, 1), "mm/dd/yyyy")
  15. vEndDate = ""
  16. vEndDate = Format(Workbooks(MyFileName).Worksheets(ws).Cells(3, 1), "mm/dd/yyyy")
  17. vExtra = ""
  18. vExtra = UCase(Trim(Workbooks(MyFileName).Worksheets(ws).Cells(4, 1)))
  19. vStr = ""
  20. If Len(vExtra) = 0 Then
  21. vStr = vStartDate & " - " & vEndDate
  22. Else
  23. vStr = vStartDate & " - " & vEndDate & " " & vExtra
  24. End If
  25. vLastRow = 0
  26. vLastRow = Workbooks(MyFileName).Worksheets(ws).Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row
  27. MySheet = ""
  28. Set MySheet = Workbooks(MyFileName).Worksheets(ws)
  29. Set MyData = MySheet.Range(Workbooks(MyFileName).Worksheets(ws).Cells(11, 13), Worksheets(ws).Cells(vLastRow, 30))
  30. Dim dBcn As New ADODB.Connection
  31. Dim dbRS As New ADODB.Recordset
  32. dBConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & MyData & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
  33. dBcn.Open dBConn
  34. vsql = ""
  35. vsql = "SELECT * FROM MyData"
  36. dbRS.Open vsql, dBcn ' type mismatch error occurs on this line of code
  37. If FirstTime = True Then
  38. Workbooks(MyFileName).Worksheets("Data").Cells(2, 1).CopyFromRecordset dbRS
  39. FirstTime = False
  40. Else
  41. vLastRow = vLastRow + 1
  42. Workbooks(MyFileName).Worksheets("Data").Cells(vLastRow, 1).CopyFromRecordset dbRS
  43. End If
  44. Set MyData = Nothing
  45. dbRS.Close
  46. dBcn.Close
  47. End If
  48. ws = ws + 1
  49. 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

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

  1. Option Explicit
  2. Sub GetData()
  3. Dim wb As Workbook, ws As Worksheet, wsData As Worksheet
  4. Dim rngData As Range, LastRow As Long, r As Long
  5. Dim dbConn As ADODB.Connection, sConn As String, rs As ADODB.Recordset
  6. Dim SQL As String
  7. Set dbConn = New ADODB.Connection
  8. ' 配置
  9. Set wb = ActiveWorkbook
  10. Set wsData = wb.Sheets("Data")
  11. wsData.UsedRange.Offset(1).ClearContents ' 保留标题
  12. ' 连接到工作簿
  13. sConn = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
  14. "Data Source=" & wb.FullName & _
  15. ";Extended Properties=""Excel 12.0 Macro;HDR=No;IMEX=1"";"
  16. 'Debug.Print sConn
  17. dbConn.Open sConn
  18. ' 扫描每个工作表
  19. For Each ws In wb.Sheets
  20. If UCase(ws.Name) = "NOTES" Or ws.Name = wsData.Name Then
  21. ' 跳过,因为宏不会从这两个工作表中提取数据
  22. Else
  23. ' 数据范围
  24. LastRow = ws.UsedRange.Row + ws.UsedRange.Rows.Count - 1
  25. If LastRow < 11 Then
  26. MsgBox "最后一行 < 11 = " & LastRow, vbCritical
  27. Exit Sub
  28. Else
  29. Set rngData = ws.Range("M11:AD" & LastRow)
  30. End If
  31. SQL = "SELECT * FROM [" & ws.Name & "$" & rngData.Address(0, 0) & "]"
  32. 'Debug.Print SQL
  33. ' 复制记录
  34. Set rs = New ADODB.Recordset
  35. rs.Open SQL, dbConn, adOpenForwardOnly
  36. With wsData
  37. If r < 2 Then r = 2
  38. .Range("A" & r).CopyFromRecordset rs
  39. r = 1 + .Cells(.Rows.Count, "A").End(xlUp).Row
  40. End With
  41. End If
  42. Next
  43. dbConn.Close
  44. Set dbConn = Nothing
  45. MsgBox r - 2 & "条记录已复制到" & wsData.Name, vbInformation
  46. End Sub
英文:

Use the address of the range in the SQL.

  1. Option Explicit
  2. Sub GetData()
  3. Dim wb As Workbook, ws As Worksheet, wsData As Worksheet
  4. Dim rngData As Range, LastRow As Long, r As Long
  5. Dim dbConn As ADODB.Connection, sConn As String, rs As ADODB.Recordset
  6. Dim SQL As String
  7. Set dbConn = New ADODB.Connection
  8. &#39; config
  9. Set wb = ActiveWorkbook
  10. Set wsData = wb.Sheets(&quot;Data&quot;)
  11. wsData.UsedRange.Offset(1).ClearContents &#39; leave header
  12. &#39; connect to workbook
  13. sConn = &quot;Provider=Microsoft.ACE.OLEDB.12.0;&quot; &amp; _
  14. &quot;Data Source=&quot; &amp; wb.FullName &amp; _
  15. &quot;;Extended Properties=&quot;&quot;Excel 12.0 Macro;HDR=No;IMEX=1&quot;&quot;;&quot;
  16. &#39;Debug.Print sConn
  17. dbConn.Open sConn
  18. &#39; scan each sheets
  19. For Each ws In wb.Sheets
  20. If UCase(ws.Name) = &quot;NOTES&quot; Or ws.Name = wsData.Name Then
  21. &#39;skip as the macro will NOT be grabbing data from these 2 worksheets
  22. Else
  23. &#39; entent of data
  24. LastRow = ws.UsedRange.Row + ws.UsedRange.Rows.Count - 1
  25. If LastRow &lt; 11 Then
  26. MsgBox &quot;Last row &lt; 11 = &quot; &amp; LastRow, vbCritical
  27. Exit Sub
  28. Else
  29. Set rngData = ws.Range(&quot;M11:AD&quot; &amp; LastRow)
  30. End If
  31. SQL = &quot;SELECT * FROM [&quot; &amp; ws.Name &amp; &quot;$&quot; &amp; rngData.Address(0, 0) &amp; &quot;]&quot;
  32. &#39;Debug.Print SQL
  33. &#39; copy records
  34. Set rs = New ADODB.Recordset
  35. rs.Open SQL, dbConn, adOpenForwardOnly
  36. With wsData
  37. If r &lt; 2 Then r = 2
  38. .Range(&quot;A&quot; &amp; r).CopyFromRecordset rs
  39. r = 1 + .Cells(.Rows.Count, &quot;A&quot;).End(xlUp).Row
  40. End With
  41. End If
  42. Next
  43. dbConn.Close
  44. Set dbConn = Nothing
  45. MsgBox r - 2 &amp; &quot; records copied to &quot; &amp; wsData.Name, vbInformation
  46. End Sub
  47. </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:

确定