VBA仍然不太好,试图学习。问题是我是否应该使用TypeArray项目创建一个用户表单,询问他们哪些项目去哪个"端口摘要"标题,然后创建一个新的TypeArray,或者只是尝试让程序以某种方式重新配置(以及 - 如何?)?
我从大量的CSV文件中获取了这些数据(这是一个片段,实际包含60 - 250行,以及5个或更多" Marker"列) - 让&#39 ; s称之为Range1:
╔════════════════════════════════╦══════════════════╦══════════════╦══════════════════╦══════════════╦══════════════════╦══════════════╗ ║ CSV File Name ║ Marker 1 ft/freq ║ Marker 1 dBm ║ Marker 2 ft/freq ║ Marker 2 dBm ║ Marker 3 ft/freq ║ Marker 3 dBm ║ ╠════════════════════════════════╬══════════════════╬══════════════╬══════════════════╬══════════════╬══════════════════╬══════════════╣ ║ TestSite_ALPHA_850_1_DTFL.csv ║ 113.82 ║ (42.88) ║ N/A ║ N/A ║ N/A ║ N/A ║ ║ TestSite_ALPHA_850_1_DTFS.csv ║ 113.82 ║ (43.96) ║ N/A ║ N/A ║ N/A ║ N/A ║ ║ TestSite_ALPHA_850_1_DTFWS.csv ║ 113.82 ║ (12.72) ║ N/A ║ N/A ║ N/A ║ N/A ║ ║ TestSite_ALPHA_850_1_RLL.csv ║ 824.04 ║ (31.87) ║ 848.97 ║ (34.09) ║ 869.04 ║ (30.19) ║ ║ TestSite_ALPHA_850_1_RLS.csv ║ 824.04 ║ (23.49) ║ 848.97 ║ (22.61) ║ 869.04 ║ (23.86) ║ ║ TestSite_ALPHA_850_1_RLWS.csv ║ 824.04 ║ (3.43) ║ 848.97 ║ (3.44) ║ 869.04 ║ (3.53) ║ ║ TestSite_ALPHA_850_1_DTFL.csv ║ 113.82 ║ (42.88) ║ N/A ║ N/A ║ N/A ║ N/A ║ ║ TestSite_ALPHA_850_2_DTFS.csv ║ 113.82 ║ (43.96) ║ N/A ║ N/A ║ N/A ║ N/A ║ ║ TestSite_ALPHA_850_2_DTFWS.csv ║ 113.82 ║ (12.72) ║ N/A ║ N/A ║ N/A ║ N/A ║ ║ TestSite_ALPHA_850_2_RLL.csv ║ 824.04 ║ (31.87) ║ 848.97 ║ (34.09) ║ 869.04 ║ (30.19) ║ ║ TestSite_ALPHA_850_2_RLS.csv ║ 824.04 ║ (23.49) ║ 848.97 ║ (22.61) ║ 869.04 ║ (23.86) ║ ║ TestSite_ALPHA_850_2_RLWS.csv ║ 824.04 ║ (3.43) ║ 848.97 ║ (3.44) ║ 869.04 ║ (3.53) ║ ║ TestSite_BETA_850_1_DTFL.csv ║ 113.82 ║ (42.88) ║ N/A ║ N/A ║ N/A ║ N/A ║ ║ TestSite_BETA_850_1_DTFS.csv ║ 113.82 ║ (43.96) ║ N/A ║ N/A ║ N/A ║ N/A ║ ║ TestSite_BETA_850_1_DTFWS.csv ║ 113.82 ║ (12.72) ║ N/A ║ N/A ║ N/A ║ N/A ║ ║ TestSite_BETA_850_1_RLL.csv ║ 824.04 ║ (31.87) ║ 848.97 ║ (34.09) ║ 869.04 ║ (30.19) ║ ║ TestSite_BETA_850_1_RLS.csv ║ 824.04 ║ (23.49) ║ 848.97 ║ (22.61) ║ 869.04 ║ (23.86) ║ ║ TestSite_BETA_850_1_RLWS.csv ║ 824.04 ║ (3.43) ║ 848.97 ║ (3.44) ║ 869.04 ║ (3.53) ║ ╚════════════════════════════════╩══════════════════╩══════════════╩══════════════════╩══════════════╩══════════════════╩══════════════╝
我从" CSV文件名"的结尾处获得以下测试类型。值并将它们分配给" TypeArray"。测试类型的调用可能存在一些差异(" RLS"可能是" RL短"例如)。
╔══════╦══════╦═══════╦═════╦═════╦══════╗ ║ DTFL ║ DTFS ║ DTFWS ║ RLL ║ RLS ║ RLWS ║ ╚══════╩══════╩═══════╩═════╩═════╩══════╝
我还创建了一个" PortArray"独特的端口(减去" TypeArray"值和" .csv" - " PortArray"(例如" TestSite_ALPHA_850_1"," TestSite_ALPHA_850_2",TestSite_Beta_850_1等 - 见底部图片。
我的问题涉及如何解决下一部分问题:我需要将上述数据汇总(端口摘要),如下所示 - 让我们称之为Range2:
╔══════════════════════╦══════════╦═════════╦═════════╦═══════════╦═══════════╦═══════════╦═══════════╦════════╦════════╦═════════╗ ║ Port ║ DTFWS PK ║ DTFL PK ║ DTFS PK ║ RLL RX PK ║ RLL TX PK ║ RLS RX PK ║ RLS TX PK ║ RWS PK ║ RWS VY ║ RWS TTL ║ ╠══════════════════════╬══════════╬═════════╬═════════╬═══════════╬═══════════╬═══════════╬═══════════╬════════╬════════╬═════════╣ ║ TestSite_ALPHA_850_1 ║ (12.72) ║ (42.88) ║ (43.96) ║ (34.09) ║ (30.19) ║ (22.61) ║ (23.86) ║ (3.44) ║ (3.53) ║ 3.49 ║ ║ TestSite_ALPHA_850_2 ║ (12.78) ║ (43.42) ║ (43.58) ║ (33.89) ║ (29.33) ║ (22.73) ║ (23.45) ║ (2.55) ║ (2.90) ║ 4.33 ║ ║ TestSite_BETA_850_1 ║ (12.51) ║ (42.59) ║ (43.77) ║ (33.50) ║ (29.67) ║ (22.26) ║ (23.12) ║ (2.45) ║ (3.23) ║ 4.24 ║ ║ TestSite_BETA_850_2 ║ (12.26) ║ (42.74) ║ (43.50) ║ (33.68) ║ (29.52) ║ (21.81) ║ (23.24) ║ (3.29) ║ (2.95) ║ 3.79 ║ ║ TestSite_GAMMA_850_1 ║ (12.06) ║ (42.78) ║ (43.74) ║ (33.10) ║ (29.61) ║ (22.21) ║ (23.13) ║ (2.86) ║ (2.82) ║ 4.34 ║ ║ TestSite_GAMMA_850_2 ║ (12.51) ║ (42.79) ║ (43.79) ║ (33.11) ║ (29.60) ║ (22.59) ║ (23.68) ║ (3.10) ║ (3.37) ║ 3.90 ║ ╚══════════════════════╩══════════╩═════════╩═════════╩═══════════╩═══════════╩═══════════╩═══════════╩════════╩════════╩═════════╝
(注意:RWS Header对应于此示例中的RLWS测试类型 - Range2标题不会发生太大变化,但测试类型值名称可能会更新)
我使用" TypeArray"使用(6)测试类型和" PortArray"填写Port Summary区域,我需要:
我在第3步被挂了,并且不知道如何确保我的TypeArray被分配到正确的Port Summary标题(他们不会出现故障 - 例如什么如果Range1中的文件名不按字母顺序排列?我的TypeArray从该列表自上而下填充,可能是RLL,RLS,RLWS,DTFL等,而我的Range2标题保持不变)和< / strong>我如何使用相同的数组项两次 - 即使用TypeArray项&#34; RLL&#34;找到Range2标题项&#34; RLL RX&#34;和&#34; RLL TX&#34;在继续进行&#34; RLS&#34;?
之前当前示例图片: Example
我使用以下方法创建Range2:
Function FillSummary()
Dim i As Integer
Dim lastrow As Integer
Dim rowSrc As Integer, colSrc As Integer 'These variables hold the row/column number for getting data
rowSrc = 1
colSrc = 1
Dim rowDest As Integer, colDest As Integer ' These variables hold the row/column number for data entry
colDest = 1
Dim rngSrc As Range, rngDest As Range 'These variables hold where the info is copied from/pasted to
'=======================
Dim tmpPort As String, tmpSweep As String, trimPort As String, trimSweep As String
Dim portArr() As String
Dim sweepArr() As String
Dim swpHeadArr() As Variant
swpHeadArr() = Array("DTFWS PK", "DTFL PK", "DTFS PK", "RLL RX PK", "RLL TX PK", _
"RLS RX PK", "RLS TX PK", "RWS PK", "RWS VY", "RWS TTL")
'=========================================================
'Find the last row of sweep data ======================
With ActiveSheet 'find and set the location of the last row of sweep files
lastrow = .Cells(.Rows.Count, "A").End(xlUp).row
End With
Set rngSrc = Range(Cells(1, 1), Cells(lastrow, 1)) 'Set the range for our source to include all sweep files
rowDest = lastrow + 2 'make our "rowSrc" variable one down from the last row of data
'======================================================
'Fill out the fields for our header info
Cells(rowDest, colDest).Value = "Port"
For i = LBound(swpHeadArr) To UBound(swpHeadArr)
colDest = colDest + 1 'increment column for sweep headers
Cells(rowDest, colDest).Value = swpHeadArr(i) 'input the sweep header value
Next 'increment next array item and loop
'===================
'Format the header row
Set rngDest = Range(Cells(rowDest, 1), Cells(rowDest, colDest))
With rngDest
.HorizontalAlignment = xlCenter
.Font.Bold = True
.Font.Size = 12
.Interior.ThemeColor = xlThemeColorDark1
.Interior.TintAndShade = -0.249977111117893
End With
'===============
'Ensure the colum widths for sweeps are "11" (readable)
Set rngDest = Range(Cells(rowDest, 3), Cells(rowDest, colDest))
With rngDest
.EntireColumn.ColumnWidth = 11
End With
'======================================================
'Start populating the arrays with each line/port & sweep type so it can be entered below
For Each cell In rngSrc
If Right(cell, 4) = ".csv" Then 'if the cell contains sweep data identified by ".csv" file type
trimPort = Left(cell, InStrRev(cell, "_") - 1) 'will cut off sweep type & "_" before it
trimSweep = Mid(cell, InStrRev(cell, "_") + 1, InStr(cell, ".csv") - 1 _
- Len(Left(cell, InStrRev(cell, "_")))) 'will cut out everything but the sweep type
' ^^^^^^^^^^
' basically, take the middle of the cell starting at the last "_",
' for a length equal to position in the cell of ".csv", minus 1, minus
' the length of the cell contents to the point of the last "_"
'===========
'If (cell <> "") And (InStr(temp, cell) = 0) Then 'empty cell error handling
If (InStr(tmpPort, trimPort) = 0) Then 'if the stuff we trimmed above doesn't equal our temp string
tmpPort = tmpPort & trimPort & "|" 'then add that stuff to our temp string with a delimiter
End If
If (InStr(tmpSweep, trimSweep) = 0) Then 'if the stuff we trimmed above doesn't equal our temp string
tmpSweep = tmpSweep & trimSweep & "|" 'then add that stuff to our temp string with a delimiter
End If
End If
Next cell
'===================
'Write the strings "tmpPort" & "tmpSweep" gathered above into our arrays
If Len(tmpPort) > 0 Then tmpPort = Left(tmpPort, Len(tmpPort) - 1)
portArr = Split(tmpPort, "|")
If Len(tmpSweep) > 0 Then tmpSweep = Left(tmpSweep, Len(tmpSweep) - 1)
sweepArr = Split(tmpSweep, "|")
'===================
'Start filling in cells in column "A" with ports from the port array
rowDest = rowDest + 1
colDest = 1
For i = LBound(portArr) To UBound(portArr)
Cells(rowDest, 1).Value = portArr(i) 'input the marker value
rowDest = rowDest + 1 'increment column for markers
Next 'increment next array item and loop
'======================================================
'Here is where I would search for each port's sweep info
'and plug it into the appropriate column in Range2
'======================================================
End Function
答案 0 :(得分:0)
将数据加载到已经完成的Range1和Range2之后,可以使用Vlookup从Range1返回标记信息。例如。如果你在你的例子中将它放在单元格B40中:
=VLOOKUP($A40 & "_" & LEFT(B$39,FIND(" ",B$39)-1) & ".csv", $A$18:$M$37, 3, FALSE)
VLookup中的第三个参数是列,因此在这种情况下将从第3列返回值:Marker 1 dBm。
您的步骤4不是特定的,但您可以更改第三个参数以适合您想要数据的列。
答案 1 :(得分:0)
我对此非常困惑,整个部分(我的主要Sub调用的一个函数)看起来仍然非常(非常)对我来说很笨拙 - 我绝对会感谢任何评论/邮件/即时通讯可能会使这种情况不那么摇摇欲坠。
我为回答我的问题而添加的内容在标注的部分中,&#34;新部分&#34;。
Function FillSummary()
Dim i As Integer, j As Integer
Dim lastrow As Integer
Dim rowSrc As Integer, colSrc As Integer 'These variables hold the row/column number for getting data
rowSrc = 1
colSrc = 1
Dim rowDest As Integer, colDest As Integer ' These variables hold the row/column number for data entry
colDest = 1
Dim rngSrc As Range, rngDest As Range 'These variables hold where the info is copied from/pasted to
'=======================
Dim tmpPort As String, tmpSweep As String, trimPort As String, trimSweep As String
Dim portArr() As String
Dim sweepArr() As String
Dim swpHeadArr() As Variant
swpHeadArr() = Array("DTFWS PK", "DTFL PK", "DTFS PK", "RLL RX PK", "RLL TX PK", _
"RLS RX PK", "RLS TX PK", "RLWS PK", "RLWS VY", "RLWS TTL") 'Had to change RWS with RLWS to match CSV names
Dim markColArr() As Variant
markColArr() = Array(3, 4, 4, 12, 14, 12, 14, 4, 6, 6) 'Tells where to find the value of each test type
Dim headColRng As Range 'hold the header columns
Dim swpHead As String 'hold the type of test from the current column's header in the summary area
Dim arrPos As Integer 'to hold the value of the position of the array item when we look it up
Dim lookupRng As Range 'to hold the position of our CSV file name find
'=========================================================
'Find the last row of sweep data ======================
With ActiveSheet 'find and set the location of the last row of sweep files
lastrow = .Cells(.Rows.Count, "A").End(xlUp).row
End With
Set rngSrc = Range(Cells(1, 1), Cells(lastrow, 1)) 'Set the range for our source to include all sweep files
rowDest = lastrow + 2 'make our "rowDest" variable one down from the last row of data
'======================================================
'Fill out the fields for our header info
Cells(rowDest, colDest).Value = "Port"
For i = LBound(swpHeadArr) To UBound(swpHeadArr)
colDest = colDest + 1 'increment column for sweep headers
Cells(rowDest, colDest).Value = swpHeadArr(i) 'input the sweep header value
Next 'increment next array item and loop
'===================
'Format the header row
Set headColRng = Range(Cells(rowDest, 1), Cells(rowDest, colDest))
With headColRng
.HorizontalAlignment = xlCenter
.Font.Bold = True
.Font.Size = 12
.Interior.ThemeColor = xlThemeColorDark1
.Interior.TintAndShade = -0.249977111117893
End With
'===============
'Ensure the colum widths for sweeps are "11" (readable)
Set headColRng = Range(Cells(rowDest, 3), Cells(rowDest, colDest))
With headColRng
.EntireColumn.ColumnWidth = 11
End With
Set headColRng = Range(Cells(rowDest, 2), Cells(rowDest, colDest))
'======================================================
'Start populating the arrays with each line/port & sweep type so it can be entered below
For Each cell In rngSrc
If Right(cell, 4) = ".csv" Then 'if the cell contains sweep data identified by ".csv" file type
trimPort = Left(cell, InStrRev(cell, "_") - 1) 'will cut off sweep type & "_" before it
trimSweep = Mid(cell, InStrRev(cell, "_") + 1, InStr(cell, ".csv") - 1 _
- Len(Left(cell, InStrRev(cell, "_")))) 'will cut out everything but the sweep type
' ^^^^^^^^^^
' basically, take the middle of the cell starting at the last "_",
' for a length equal to position in the cell of ".csv", minus 1, minus
' the length of the cell contents to the point of the last "_"
'===========
'If (cell <> "") And (InStr(temp, cell) = 0) Then 'empty cell error handling
If (InStr(tmpPort, trimPort) = 0) Then 'if the stuff we trimmed above doesn't equal our temp string
tmpPort = tmpPort & trimPort & "|" 'then add that stuff to our temp string with a delimiter
End If
If (InStr(tmpSweep, trimSweep) = 0) Then 'if the stuff we trimmed above doesn't equal our temp string
tmpSweep = tmpSweep & trimSweep & "|" 'then add that stuff to our temp string with a delimiter
End If
End If
Next cell
'===================
'Write the strings "tmpPort" & "tmpSweep" gathered above into our arrays
If Len(tmpPort) > 0 Then tmpPort = Left(tmpPort, Len(tmpPort) - 1)
portArr = Split(tmpPort, "|")
If Len(tmpSweep) > 0 Then tmpSweep = Left(tmpSweep, Len(tmpSweep) - 1)
sweepArr = Split(tmpSweep, "|")
'===================
'Start filling in cells in column "A" with ports from the port array
rowDest = rowDest + 1
colDest = 1
For i = LBound(portArr) To UBound(portArr)
Cells(rowDest, 1).Value = portArr(i) 'input the marker value
rowDest = rowDest + 1 'increment column for markers
Next 'increment next array item and loop
'======================================================
'======================================================
'New section ==========================================
'As a stop-gap, just to get something going, I've implemented the following code to get the summary.
'However, if the rows of file names are not in alpha order, or one is missing, or anything else goes wrong
' this will fail out.
rowDest = lastrow + 3
'===================
' 1) Cycle through each row of ports
For i = LBound(portArr) To UBound(portArr)
colDest = 2
j = 0
'===============
' 2) Cycle through each column of each of those rows
For Each cell In headColRng
'===========
' 3) Check active column header row for type of test (string up to the space) & copy that type
swpHead = Left(cell, InStr(cell, " ") - 1) 'will cut off everything after the type
'===========
' 4) Check sweepArr for the type we copied and return the index ("i")
arrPos = Application.Match(swpHead, sweepArr, False) - 1
'=======
'purely for testing - remove later
'Cells(rowDest, colDest).Value = portArr(i) & "_" & sweepArr(arrPos)
'=======
'=======
' 5) search the Range1 CSV File names for a match to [current row Port] &"_"& sweepArr(arrPos)
Set lookupRng = rngSrc.Find(What:=portArr(i) & "_" & sweepArr(arrPos), LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not lookupRng Is Nothing Then
rowSrc = lookupRng.row
Else
MsgBox ("Can't find the sweep for value" _
& vbCrLf & portArr(i) & "_" & sweepArr(arrPos) _
& vbCrLf & "Please check that this sweep exists")
Cells(rowDest, colDest).Value = "NoSweep"
GoTo NextJ
End If
'===========
' 6) return the value from the column "#" columns to the right
' & plug that value into the current row/column
If colDest < 11 Then
Cells(rowDest, colDest).Value = Cells(rowSrc, markColArr(j)).Value
With Cells(rowDest, colDest)
.NumberFormat = "0.00_);[Red](0.00)"
End With
Else 'unless we're at RLWS "total", then we use a formula
Cells(rowDest, colDest).Value = (Cells(rowDest, colDest - 1).Value + _
Cells(rowDest, colDest - 2).Value) / -2
With Cells(rowDest, colDest)
.NumberFormat = "0.00_);[Red](0.00)"
End With
End If
NextJ: 'where a sweep-not-found error takes us
j = j + 1 'increment array placeholder
colDest = colDest + 1 'next column
Next cell
rowDest = rowDest + 1 'next row
Next
'======================================================
'======================================================
End Function