我必须从一个Excel工作表中选择数据并复制到另一个工作表中,但是我需要在复制数据的过程中实现以下目的:
对于原始工作表的每一行,按列选择单元格(我可以预定义,也许使用数组或其他内容)。
操纵数据以更改新工作表中的方向。见下面的截图。
很难准确解释我的意思所以我希望我的截图能够传达我所需要的内容。
对于每一行都有一个通道值,我需要按通道排序并压缩所有结果。还需要根据限制检查结果,但在解决此问题后我可以跨过该结果。
我的代码如下,我感谢可能有错误,因为这是我的第一个脚本。不要介意按渠道排序数据我到目前为止都在努力选择我想要的列并将它们完全复制到新工作表中。
代码的第一部分是检查并创建一个新的工作表。之后,它继续定义变量和数组,我可以预定义我想要的列。它完成了一个循环,检查x行数(虽然我确实希望它迭代尽可能多的行),并且内部每行有另一个循环,根据我的预定义列抓取单元格。
调试时,它会在循环内部底部的工作表复制功能中显示为对象或应用程序错误。我不确定我哪里出错了。我哪里出错了,是否有更好的方法来攻击它?
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
答案 0 :(得分:1)
顺便说一句,这里有一些代码可以做你想要的:
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 :(得分:1)
有多种方法可以解决这个问题!以下三个可以在this file中找到。
<强> 1。数据透视表
Mode
拖到“行标签”框,将“频道”拖到“列标签”列,将“结果”拖到“值”完成!
<强> 2。式强>
此解决方案仅适用于模式和通道的名称:
=INDEX(Sheet1!$D$2:$D$10,MATCH($A2&"_"&B$1,Sheet1!$A$2:$A$10&"_"&Sheet1!$C$2:$C$10,0))
这是一个数组公式,即输入 Ctrl - Shift - Enter 3.复制表中所有剩余单元格的公式
第3。宏强>
这个宏可以完成这项任务 - 虽然它假设模式和通道已经排序。您需要为结果表rngHeader
的左上角单元命名,然后运行以下代码:
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