Copying rows from several sheets, where sheet data exists, to one sheet of another file in Excel VBA

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

Copying rows from several sheets, where sheet data exists, to one sheet of another file in Excel VBA

问题

I need to copy rows with four columns from one workbook containing four sheets "data.xlsx" (sheets 1, 2, 3, 4) to one sheet on another workbook named "newdata.xlsm" (sheet 1).

For sheets 1, 2, 3, 4 in "data.xlsx" the number of rows can be anywhere from 0 to 60 (usually 0 to 20 rows).

When one or several sheets in data.xlsx has zero rows the macro generates

VBA Error 1004 – Application-Defined or Object-Defined Error

If for example sheet 2 has zero rows. Excel gets an error on:

  1. 'copy
  2. column 1 worksheets("worksheet2").cells(p,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,1)

as q=0. I understand it is not possible to copy text to row = 0.

I started to dabble with "goto"-statements but quickly surrendered as I realized I was in deep water.

  1. sub copyfile
  2. 'read data.xlsx file
  3. 'open data file
  4. workbooks.open filename :=thisworkbook.path & "\data.xlsx"
  5. dim x as integer
  6. 'dim lr as long
  7. lr= cells(rows.count,1).end(xlup).row
  8. for x = 2 to lr
  9. 'copy rows from sheet1 on data.xlsx to new file, new file called "newdata.xlsm"
  10. 'copy column 1
  11. worksheets("worksheet1").cells(x,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(x,1)
  12. 'copy column 2
  13. worksheets("worksheet1").cells(x,2).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(x,2)
  14. 'copy column 3
  15. worksheets("worksheet1").cells(x,3).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(x,3)
  16. 'copy column 4
  17. worksheets("worksheet1").cells(x,4).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(x,4)
  18. next x
  19. windows("data.xlsx").Activate
  20. Sheets("Worksheet2").Activate
  21. 'dim copy worksheet 2
  22. dim y as integer
  23. dim z as integer
  24. dim lr_y as long
  25. 'no of rows on worksheet2
  26. lr_y = cells(rows.count,1).end(xlup).row
  27. For y = 2 to lr_y
  28. For z = (y + x) -2 to lr_y + x - 2
  29. 'copy rows from sheet2 on data.xlsx to new file, new file called "newdata.xlsm"
  30. 'copy column 1
  31. worksheets("worksheet2").cells(y,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(z,1)
  32. 'copy column 2
  33. worksheets("worksheet2").cells(y,2).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(z,2)
  34. 'copy column 3
  35. worksheets("worksheet2").cells(y,3).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(z,3)
  36. 'copy column 4
  37. worksheets("worksheet2").cells(y,4).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(z,4)
  38. next z
  39. next y
  40. windows("data.xlsx").Activate
  41. Sheets("Worksheet3").Activate
  42. 'dim copy worksheet 3
  43. dim p as integer
  44. dim q as integer
  45. dim lr_p as long
  46. 'no of rows on worksheet3
  47. lr_p = cells(rows.count,1).end(xlup).row
  48. For p = 2 to lr_p
  49. For q = (p+z) -2 to lr_p + z - 2
  50. 'copy column 1
  51. worksheets("worksheet3").cells(p,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,1)
  52. 'copy column 2
  53. worksheets("worksheet3").cells(p,2).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,2)
  54. 'copy column 3
  55. worksheets("worksheet3").cells(p,3).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,3)
  56. 'copy column 4
  57. worksheets("worksheet3").cells(p,4).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,4)
  58. next q
  59. next p
  60. windows("data.xlsx").Activate
  61. Sheets("Worksheet4").Activate
  62. 'dim copy worksheet 3
  63. dim r as integer
  64. dim s as integer
  65. 'no of rows on worksheet4
  66. dim lr_p as long
  67. lr_p = cells(rows.count,1).end(xlup).row
  68. For r = 2 to lr_r
  69. For s = (r+q) -2 to lr_r + q - 2
  70. 'copy column 1
  71. worksheets("worksheet4").cells(r,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(s,1)
  72. 'copy column 2
  73. worksheets("worksheet4").cells(r,2).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(s,2)
  74. 'copy column 3
  75. worksheets("worksheet4").cells(r,3).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(s,3)
  76. 'copy column 4
  77. worksheets("worksheet4").cells(r,4).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(s,4)
  78. next s
  79. next r
  80. workbooks("data.xlsx").close

I tried changing:

  1. For q = (p+z) -2 to lr_p + z - 2

to include variants of x, however, this did not work as I need the code to function in both cases, if rows are populated or not.

英文:

I need to copy rows with four columns from one workbook containing four sheets "data.xlsx" (sheets 1, 2, 3, 4) to one sheet on another workbook named "newdata.xlsm" (sheet 1).

For sheets 1, 2, 3, 4 in "data.xlsx" the number of rows can be anywhere from 0 to 60 (usually 0 to 20 rows).

When one or several sheets in data.xlsx has zero rows the macro generates

>VBA Error 1004 – Application-Defined or Object-Defined Error

If for example sheet 2 has zero rows. Excel gets an error on:

  1. 'copy
  2. column 1 worksheets("worksheet2").cells(p,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,1)

as q=0. I understand it is not possible to copy text to row = 0.

I started to dabble with "goto"-statements but quickly surrendered as I realized I was in deep water.

  1. sub copyfile
  2. 'read data.xlsx file
  3. 'open data file
  4. workbooks.open filename :=thisworkbook.path & "\data.xlsx"
  5. dim x as integer
  6. 'dim lr as long
  7. lr= cells(rows.count,1).end(xlup).row
  8. for x = 2 to lr
  9. 'copy rows from sheet1 on data.xlsx to new file, new file called "newdata.xlsm"
  10. 'copy column 1
  11. worksheets("worksheet1").cells(x,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(x,1)
  12. 'copy column 2
  13. worksheets("worksheet1").cells(x,2).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(x,2)
  14. 'copy column 3
  15. worksheets("worksheet1").cells(x,3).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(x,3)
  16. 'copy column 4
  17. worksheets("worksheet1").cells(x,4).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(x,4)
  18. next x
  19. windows("data.xlsx").Activate
  20. Sheets("Worksheet2").Activate
  21. 'dim copy worksheet 2
  22. dim y as integer
  23. dim z as integer
  24. dim lr_y as long
  25. 'no of rows on worksheet2
  26. lr_y = cells(rows.count,1).end(xlup).row
  27. For y = 2 to lr_y
  28. For z = (y + x) -2 to lr_y + x - 2
  29. 'copy rows from sheet2 on data.xlsx to new file, new file called "newdata.xlsm"
  30. 'copy column 1
  31. worksheets("worksheet2").cells(y,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(z,1)
  32. 'copy column 2
  33. worksheets("worksheet2").cells(y,2).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(z,2)
  34. 'copy column 3
  35. worksheets("worksheet2").cells(y,3).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(z,3)
  36. 'copy column 4
  37. worksheets("worksheet2").cells(y,4).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(z,4)
  38. next z
  39. next y
  40. windows("data.xlsx").Activate
  41. Sheets("Worksheet3").Activate
  42. 'dim copy worksheet 3
  43. dim p as integer
  44. dim q as integer
  45. dim lr_p as long
  46. 'no of rows on worksheet3
  47. lr_p = cells(rows.count,1).end(xlup).row
  48. For p = 2 to lr_p
  49. For q = (p+z) -2 to lr_p + z - 2
  50. 'copy column 1
  51. worksheets("worksheet3").cells(p,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,1)
  52. 'copy column 2
  53. worksheets("worksheet3").cells(p,2).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,2)
  54. 'copy column 3
  55. worksheets("worksheet3").cells(p,3).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,3)
  56. 'copy column 4
  57. worksheets("worksheet3").cells(p,4).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(q,4)
  58. next q
  59. next p
  60. windows("data.xlsx").Activate
  61. Sheets("Worksheet4").Activate
  62. 'dim copy worksheet 3
  63. dim r as integer
  64. dim s as integer
  65. 'no of rows on worksheet4
  66. dim lr_p as long
  67. lr_p = cells(rows.count,1).end(xlup).row
  68. For r = 2 to lr_r
  69. For s = (r+q) -2 to lr_r + q - 2
  70. 'copy column 1
  71. worksheets("worksheet4").cells(r,1).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(s,1)
  72. 'copy column 2
  73. worksheets("worksheet4").cells(r,2).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(s,2)
  74. 'copy column 3
  75. worksheets("worksheet4").cells(r,3).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(s,3)
  76. 'copy column 4
  77. worksheets("worksheet4").cells(r,4).copy workbooks("newdata.xlsm").worksheets("sheet1").cells(s,4)
  78. next s
  79. next r
  80. workbooks("data.xlsx").close

I tried changing:

  1. For q = (p+z) -2 to lr_p + z - 2

to include variants of x however this did not work as I need the code to function in both cases, if rows are populated or not.

答案1

得分: 2

以下是代码部分的中文翻译:

  1. Sub copyfile()
  2. Dim wb As Workbook, wbData As Workbook, i As Long, wsName, lr As Long, ws As Worksheet
  3. Dim pasteRow As Long
  4. Set wb = ThisWorkbook
  5. Set wbData = Workbooks.Open(Filename:=ThisWorkbook.Path & "\data.xlsx")
  6. pasteRow = 2 '从这里开始粘贴
  7. For Each wsName In Array("worksheet1", "worksheet2", "worksheet3", "worksheet4")
  8. Set ws = wbData.Worksheets(wsName)
  9. lr = LastOccupiedRow(ws)
  10. If lr > 1 Then '2行及以后有数据吗?
  11. ws.Range("A2:D" & lr).Copy wb.Worksheets("sheet1").Cells(pasteRow, "A")
  12. pasteRow = pasteRow + (lr - 1)
  13. End If
  14. Next wsName
  15. wbData.Close False
  16. End Sub
  17. Function LastOccupiedRow(ws As Worksheet) As Long
  18. Dim f As Range
  19. Set f = ws.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
  20. If Not f Is Nothing Then LastOccupiedRow = f.Row
  21. End Function

请注意,这是您提供的代码的中文翻译,不包括问题或其他内容。

英文:

Much tidier to copy/paste the whole block, and use a loop for the worksheets being copied:

  1. Sub copyfile()
  2. Dim wb As Workbook, wbData As Workbook, i As Long, wsName, lr As Long, ws As Worksheet
  3. Dim pasteRow As Long
  4. Set wb = ThisWorkbook
  5. Set wbData = Workbooks.Open(Filename:=ThisWorkbook.Path & "\data.xlsx")
  6. pasteRow = 2 'start pasting here
  7. For Each wsName In Array("worksheet1", "worksheet2", "worksheet3", "worksheet4")
  8. Set ws = wbData.Worksheets(wsName)
  9. lr = LastOccupiedRow(ws)
  10. If lr > 1 Then 'any data from row 2 on?
  11. ws.Range("A2:D" & lr).copy wb.Worksheets("sheet1").Cells(pasteRow, "A")
  12. pasteRow = pasteRow + (lr - 1)
  13. End If
  14. Next wsName
  15. wbData.Close False
  16. End Sub
  17. Function LastOccupiedRow(ws As Worksheet) As Long
  18. Dim f As Range
  19. Set f = ws.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
  20. If Not f Is Nothing Then LastOccupiedRow = f.Row
  21. End Function

huangapple
  • 本文由 发表于 2023年4月19日 22:06:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76055499.html
匿名

发表评论

匿名网友

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

确定