For each row, copy specific cells by predefined columns and paste values โ€‹โ€‹into alternative predefined columns on a separate sheet

I need to select data from one Excel worksheet and copy them to another worksheet, however I need to perform the following data copy operations:

  • For each row in the source sheet, select cells by column (which I can predefine, possibly using an array or something else).

  • Manipulate data to change the orientation on a new sheet. See screenshot below.

Itโ€™s hard for me to explain exactly what I mean, so I hope that my screenshot will tell me what I need.

enter image description here

For each row there is a channel value, I need to order and condense all the results on the channel. There is also a need to check the results with a constraint, but I can cross them after solving this problem.

I have my code below, I appreciate that there may be errors, as this is my first script. Do not pay attention to the data on the channels that I still struggle with, even to select the necessary columns and copy them to a new worksheet.

The first part of the code is checking and creating a new worksheet. After that, he moves on to defining the variables and arrays that I can predefine the columns that I want. It ends with a loop that checks the number of rows (although I want it to repeat as many rows as there are), and inside that there is another loop for each row, captures a cell based on my predefined columns.

When debugging, it is displayed as an error of an object or application in the copy sheet function right below inside the loops. I am not sure where I am going wrong. Where am I mistaken and is there a better way to attack this?

Sub Process_Results() 'User defines the worksheets for this script sourcedatasheet_name = InputBox("Enter the customer data sheet name: ", "Enter Worksheet Name") For rep = 1 To (Worksheets.Count) If LCase(Sheets(rep).Name) = LCase(sourcedatasheet_name) Then Exit For ElseIf (rep = Worksheets.Count) And (LCase(Sheets(rep).Name) <> LCase(sourcedatasheet_name)) Then MsgBox "This sheet does not exist!" Exit Sub End If Next destinationdatasheet_name = InputBox("Enter the destination worksheet name to write the data to: ", "Enter Destination Worksheet Name") For rep = 1 To (Worksheets.Count) If LCase(Sheets(rep).Name) = LCase(destinationdatasheet_name) Then MsgBox "This sheet already exists!" Exit Sub End If Next Sheets.Add After:=Sheets(Sheets.Count) Sheets(ActiveSheet.Name).Name = destinationdatasheet_name 'These are the variables for referencing data sets in the source sheet Dim source_testmodel Dim source_testcasename Dim source_measurementname Dim source_carrierfrequency Dim source_limitlow Dim source_limithigh Dim source_measuredresult Dim source_measurementunit 'These are the variables for referencing data set columns in the processed data sheet Dim destination_testmodel Dim destination_testcasename Dim destination_measurementname Dim destination_carrierfrequency_bottomchannel Dim destination_carrierfrequency_middlechannel Dim destination_carrierfrequency_topchannel Dim destination_measuredresult 'Define the column number and cell column reference for each data set that will be used to retrieve information from the source sheet source_testmodel = 9 source_testname = 11 source_measurementname = 12 source_measuredcarrierfrequency = 13 source_measurementlimitlow = 15 source_measurementlimithigh = 16 source_measuredresult = 17 source_measurementunit = 18 Dim array_source_fields(8) As Variant array_source_fields(1) = source_testmodel array_source_fields(2) = source_testname array_source_fields(3) = source_measurementname array_source_fields(4) = source_measuredcarrierfrequency array_source_fields(5) = source_measurementlimitlow array_source_fields(6) = source_measurementlimithigh array_source_fields(7) = source_measuredresult array_source_fields(8) = source_measurementunit 'Define the column number and cell column reference for each data set that will be used to write information to the processing sheet destination_testmodel = 1 destination_testname = 2 destination_measurementname = 3 destination_channelbottom = 4 destination_channelmiddle = 5 destination_channeltop = 6 Dim array_processed_fields(6) As Variant array_processed_fields(1) = destination_testmodel array_processed_fields(2) = destination_testname array_processed_fields(3) = destination_measurementname array_processed_fields(4) = destination_channelbottom array_processed_fields(5) = destination_channelmiddle array_processed_fields(6) = destination_channeltop 'Start processing data Dim y As Variant Dim lastrow As Long For x = 1 To 100 'row 'lastrow=activesheet.usedrange.specialcells(xlCellTypeLastCell) For Each y In array_source_fields 'y = LBound(Application.Transpose(array_source_fields)) To UBound(Application.Transpose(array_source_fields)) Sheets(sourcedatasheet_name).Cells(x, y).Copy Destination:=Sheets(destinationdatasheet_name).Cells(x, y) Next y Next x End Sub 
+4
source share
2 answers

There are several ways to solve this problem! The following three can be found in this file . enter image description here

1. Summary table

  • Insert tab-> Tables-> Pivot table
  • Select your data as a range for analysis and click "OK"
  • Drag the Mode field into the Row Labels, Channel box in the Column Characters and Results columns onto Values
  • Pivot table elements -> Design tab โ†’ Layout โ†’ Highlights โ†’ Off for Rows and Columns

Done!

2. The formula

This solution is applicable only if the name of the modes and channels is known:

  • Put all mode names in the first column, all channel names in the first row, i.e. create header lines. In the formula below, I assume that the header row is row 1, and the header column is A in sheet2 and that the data is in Sheet 1, starting at cell A1
  • In cell B2, enter the following formula:
  = INDEX (Sheet1! $ D $ 2: $ D $ 10, MATCH ($ A2 & "_" & B $ 1, Sheet1! $ A $ 2: $ A $ 10 & "_" & Sheet1! $ C $ 2: $ C $ 10.0))

This is an array formula, i.e. enter it using Ctrl - Shift - Enter 3. Copy the formula to all the other cells in the table

3. Macro

This macro will complete the task - although it assumes that the modes and channels are sorted. You need to specify the top left cell of your rngHeader result rngHeader , and then run this code:

 Sub FillTable() Dim rngSource As Range, rngTarget As Range Dim lngModeCount As Long, lngChannelCount As Long Set rngSource = Range("A2") Set rngTarget = Range("rngHeader") 'Clear old result With rngTarget If .Offset(1) <> "" And .Offset(, 1) <> "" Then .Resize(.End(xlDown).Row - .Row + 1, .End(xlToRight).Column - .Column + 1).Clear rngTarget = "(cell is named ""rngHeader"")" End If End With While rngSource.Value <> "" If rngSource.Offset(-1) <> rngSource Then lngModeCount = lngModeCount + 1 lngChannelCount = 0 rngTarget.Offset(lngModeCount) = rngSource rngTarget.Offset(lngModeCount).Font.Bold = True End If lngChannelCount = lngChannelCount + 1 If lngModeCount = 1 Then rngTarget.Offset(, lngChannelCount) = rngSource.Offset(, 2) rngTarget.Offset(, lngChannelCount).Font.Bold = True End If rngTarget.Offset(lngModeCount, lngChannelCount) = rngSource.Offset(, 3) Set rngSource = rngSource.Offset(1) Wend End Sub 
+1
source

By the way, here is some code that will do what you want:

 Const FIRST_CELL_IN_SOURCE_DATA = "$A$4" Const FIRST_CELL_IN_DEST_DATA = "$A$2" Const COL_SOURCE_MODE = 0 Const COL_SOURCE_DESC = 1 Const COL_SOURCE_CHANNEL = 2 Const COL_SOURCE_RESULT = 3 Const COL_SOURCE_LIMIT = 4 Const COL_DEST_MODE = 1 Const COL_DEST_DESC = 1 Const COL_DEST_RESULT = 4 Const COL_DEST_FIRST_CHANNEL = 3 Const ROW_DEST_HEADER = 1 Private wksSource As Worksheet Private wksDest As Worksheet Sub Process_Results() If GetSourceSheet = False Then Exit Sub If CreateDestinationSheet = False Then Exit Sub CopyDataSet End Sub Private Function GetSourceSheet() As String 'User defines the worksheets for this script sourcedatasheet_name = InputBox("Enter the customer data sheet name: ", "Enter Worksheet Name") For rep = 1 To (Worksheets.Count) If LCase(Sheets(rep).Name) = LCase(sourcedatasheet_name) Then Exit For ElseIf (rep = Worksheets.Count) And (LCase(Sheets(rep).Name) <> LCase(sourcedatasheet_name)) Then MsgBox "This sheet does not exist!" Exit Function End If Next Set wksSource = Sheets(sourcedatasheet_name) GetSourceSheet = True End Function Private Function CreateDestinationSheet() As String destinationdatasheet_name = InputBox("Enter the destination worksheet name to write the data to: ", "Enter Destination Worksheet Name") For rep = 1 To (Worksheets.Count) If LCase(Sheets(rep).Name) = LCase(destinationdatasheet_name) Then MsgBox "This sheet already exists!" Exit Function End If Next Sheets.Add After:=Sheets(Sheets.Count) Sheets(ActiveSheet.Name).Name = destinationdatasheet_name Set wksDest = Sheets(destinationdatasheet_name) AddHeaders CreateDestinationSheet = True End Function Private Sub CopyDataSet() Dim rngSourceRange As Range Dim rngDestRange As Range Set rngSourceRange = wksSource.Range(FIRST_CELL_IN_SOURCE_DATA) Set rngDestRange = wksDest.Range(FIRST_CELL_IN_DEST_DATA) rngDestRange.Activate Do Until rngSourceRange.Value = "" CopyRowToDest rngSourceRange, rngDestRange Set rngSourceRange = rngSourceRange.Offset(1) Loop End Sub Private Sub AddHeaders() Dim rng As Range Set rng = wksDest.Cells(ROW_DEST_HEADER, 1) rng.Value = "Mode" rng.Offset(, 1).Value = "Test" End Sub Private Function GetColumnForChannel(ByVal Channel As String) As Long Dim rng As Range Set rng = wksDest.Cells(ROW_DEST_HEADER, COL_DEST_FIRST_CHANNEL) Do Until rng.Value = "" If rng.Value = Channel Then GetColumnForChannel = rng.Column - 1 Exit Function End If Set rng = rng.Offset(, 1) Loop rng.Value = Channel GetColumnForChannel = rng.Column - 1 End Function Private Sub MoveToModeRow(ByVal Mode As String) If ActiveCell.Value = Mode Then Exit Sub If ActiveCell.Address = FIRST_CELL_IN_DEST_DATA And ActiveCell.Value = "" Then ActiveCell.Value = Mode Exit Sub End If If Val(ActiveCell.Value) < Val(Mode) And ActiveCell.Offset(1).Value = "" Then ActiveCell.Offset(1).Activate ActiveCell.Value = Mode Exit Sub End If Dim rng As Range Set rng = wksDest.Range(FIRST_CELL_IN_DEST_DATA) Do Until rng.Value = "" If rng.Value = Mode Then rng.Activate Exit Sub End If Set rng = rng.Offset(1) Loop rng.Value = Mode rng.Activate End Sub Private Sub CopyRowToDest(ByRef rngSourceRange As Range, ByRef rngDestRange As Range) MoveToModeRow rngSourceRange.Offset(, COL_SOURCE_MODE).Value Dim lngCol As Long lngCol = GetColumnForChannel(rngSourceRange.Offset(, COL_SOURCE_CHANNEL).Value) ActiveCell.Offset(, lngCol).Value = rngSourceRange.Offset(, COL_SOURCE_RESULT).Value ActiveCell.Offset(, COL_DEST_DESC).Value = rngSourceRange.Offset(, COL_SOURCE_DESC).Value End Sub 
+1
source

All Articles