Forum Discussion
VBA or Power Query help: Iterate copy/paste from one sheet to another and save each iteration
- May 19, 2023
You can started with the VBA code to achieve your task.
Here's an example VBA code that you can use as a starting point:
Sub IterateAndCopyPaste() Dim wb As Workbook Dim wsInputs As Worksheet Dim wsAnalysis As Worksheet Dim wsSummaries As Worksheet Dim tblInputs As ListObject Dim tblAnalysis As ListObject Dim tblSummaries As ListObject Dim inputRow As ListRow Dim analysisRow As ListRow Dim lastRow As Long Dim i As Long ' Set references to the workbook and worksheets Set wb = ThisWorkbook Set wsInputs = wb.Worksheets("All Inputs") Set wsAnalysis = wb.Worksheets("Analysis") Set wsSummaries = wb.Worksheets("Summaries") ' Set references to the tables Set tblInputs = wsInputs.ListObjects("Inputs") Set tblAnalysis = wsAnalysis.ListObjects("Analysis_T") Set tblSummaries = wsSummaries.ListObjects("Summaries") ' Loop through each row in the Inputs table For i = 1 To tblInputs.DataBodyRange.Rows.Count ' Get the current input row Set inputRow = tblInputs.ListRows(i) ' Clear the cells in Analysis_T tblAnalysis.DataBodyRange.ClearContents ' Copy the input row to the first row of Analysis_T inputRow.Range.Copy tblAnalysis.DataBodyRange.Rows(1) ' Wait for calculations to complete (if necessary) ' Add code here to wait for the calculations to complete ' Copy all rows from Analysis_T to Summaries lastRow = tblSummaries.DataBodyRange.Rows.Count tblAnalysis.DataBodyRange.Copy Destination:=tblSummaries.DataBodyRange.Offset(lastRow) ' Delete rows from Summaries where Result 2 is "No" DeleteRowsWithNoResult2 wsSummaries, tblSummaries ' Clear the clipboard Application.CutCopyMode = False Next i End Sub Sub DeleteRowsWithNoResult2(ws As Worksheet, tbl As ListObject) Dim result2Column As Range Dim cell As Range ' Set the Result 2 column range Set result2Column = tbl.ListColumns("Result 2").DataBodyRange ' Loop through each cell in the Result 2 column For Each cell In result2Column.Cells ' Check if the value is "No" and delete the entire row If cell.Value = "No" Then cell.EntireRow.Delete End If Next cell End SubPlease note that this is a basic example, and you may need to modify it based on your specific workbook structure and requirements. You'll also need to add code to wait for the calculations to complete, as indicated in the comments.
To run the code, press Alt+F11 to open the VBA editor in Excel, insert a new module, and paste the code into the module. You can then run the IterateAndCopyPaste macro to perform the desired iterations.
You can achieve the desired task using Power Query too in Excel.
Here's a step-by-step solution using Power Query:
- Open your Excel workbook and go to the "Data" tab.
- Click on "Get Data" and select "From Other Sources" -> "Blank Query". This will open the Power Query Editor.
- In the Power Query Editor, go to the "Home" tab and click on "Advanced Editor".
- Replace the existing code with the following Power Query code:
let Source = Excel.CurrentWorkbook(){[Name="Inputs"]}[Content], #"Filtered Rows" = Table.SelectRows(Source, each [#"Result 2"] = "Yes"), #"Removed Columns" = Table.RemoveColumns(#"Filtered Rows", {"Result 2"}), #"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Model", "Parts"}, {"Calculation 1", "Result 1"}, {"Calculation 2", "Result 2"}, {"Calculation 3", "Result 3"}}), #"Appended Queries" = Table.Combine({#"Renamed Columns", #"Renamed Columns", #"Renamed Columns"}) // Replace the number of repetitions here in #"Appended Queries" ā5. In the code above, replace "Inputs" with the actual name of your table in the "All Inputs" sheet.
6. Replace the comment // Replace the number of repetitions here with the actual number of times you want to repeat the rows.
7. Click on "Done" to close the Power Query Editor.
This Power Query code will filter the rows based on "Result 2" column, remove the "Result 2" column, rename the columns accordingly, and append the resulting table multiple times based on the specified number of repetitions.
Once you've completed the above steps, Power Query will load the transformed data into a new table in Excel. The table will contain the desired iterations based on your requirements.
You can refresh the data in the table whenever needed by clicking on "Data" -> "Refresh All".
I hope the proposal solutions, with AI helps, using VBA or Power Query meets your requirements.
With out opening any file (for own security reasons at the moment) maybe you can replace the line inputRow.Range.Copy tblModel.DataBodyRange.Rows(1) with the following code:
inputRow.Range.Copy
tblModel.DataBodyRange.Rows(1).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
This code copies the range from inputRow.Range and then pastes only the values into tblModel.DataBodyRange.Rows(1) using the PasteSpecial method. The Application.CutCopyMode = False line is added to clear the clipboard.
Regarding the speed optimization, here are a few suggestions:
- Disable screen updating and events: Add Application.ScreenUpdating = False and Application.EnableEvents = False before the loop and set them back to True after the loop completes. This prevents unnecessary screen refreshing and event triggering during the execution of the loop.
- Use arrays for data manipulation: Load the input range and destination range into arrays, perform the necessary operations in memory, and then write the updated arrays back to the worksheet. Working with arrays can significantly improve the performance compared to reading and writing cell-by-cell.
- Minimize interactions with the worksheet: Instead of repeatedly clearing the contents of tables or individual ranges, consider resizing and overwriting existing data directly.
- Use efficient methods for deleting blank rows: If you need to delete blank rows, consider using advanced filtering or the AutoFilter method to identify and delete the blank rows in a single operation, rather than row-by-row deletion.
Remember to thoroughly test any modifications to ensure they produce the desired results and maintain data integrity.
These suggestions are general performance improvement techniques that can be applied to various scenarios.
Thank you for the suggestions! I will be sure to implement those performance techniques. I will definitely mark your responses as the Best Answers but am leaving this post open since I am adding more functionality to the code and will likely need some help when I get there.