我希望这是问这个问题的正确地方。 我有一个大数据集,我在这里展示了简化的数据集:
我需要检查 C 到 E 列中的单元格中是否有“x”值。如果他们这样做了,只有那时,我需要将它们转移到第二个表中,以及它们在 A 和 B 列中的相应值。结果应该如下所示:
我尝试使用 If 函数以及 INDEX 函数和 VBA 编码,但我似乎不太能完成它 - 如果你能帮助我一点,那就太棒了。我的问题是,如果一行中有多个“x”值,我不知道如何告诉excel我需要第一个和第二个单元格以及两个单元格中的相应值 A 和B.
由于OP已标记
Excel
,如果使用MS365
,则可以使用以下公式:
=HSTACK(TOCOL(IFS(C2:E4="x",C1:E1),3),TEXTSPLIT(TEXTAFTER("|"&TOCOL(IFS(C2:E4="x",B2:B4&"|"&A2:A4),3),"|",{1,2}),"|"))
使用 LET() 使可读性更容易,
=LET(
α, TOCOL(IFS(C2:E4="x",C1:E1),3),
φ, TOCOL(IFS(C2:E4="x",B2:B4&"|"&A2:A4),3),
HSTACK(α,TEXTSPLIT(TEXTAFTER("|"&φ,"|",{1,2}),"|")))
注意: 上面显示的公式不适用于
Structured References
,因为它会给出 #SPILL!
错误。
这可以使用 POWER QUERY 快速轻松地完成。要使用上述过程实现此目的,请使用POWER QUERY窗口
UI
遵循以下简单步骤:
Table1
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Name", "Value"}, "Attribute", "Value.1"),
#"Reordered Columns" = Table.ReorderColumns(#"Unpivoted Other Columns",{"Attribute", "Value", "Name", "Value.1"}),
#"Removed Columns" = Table.RemoveColumns(#"Reordered Columns",{"Value.1"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Attribute", "Frame"}})
in
#"Renamed Columns"
这个编码很简单,我不知道该解释什么。它将数据读入内存(二维数组),创建结果数组,循环数据,填充结果数组,最后将结果数组写入 Excel。
Option Explicit
Sub ConvertMyData(sourceRange As Range, destRange As Range)
' read data into memory
Dim data, row As Long, col As Long
data = sourceRange.CurrentRegion.Value
' Count number of needed results values
Dim rowcount As Long
rowcount = WorksheetFunction.CountIf(sourceRange.CurrentRegion, "x")
If rowcount = 0 Then
MsgBox "Nothing selected."
Exit Sub ' Nothing marked with x
End If
' Create result array
ReDim result(1 To rowcount + 1, 1 To 3) As Variant
Dim resultRow As Long
' Prepare Header
result(1, 1) = "Frame"
result(1, 2) = "Value"
result(1, 3) = "Name"
' Fill result array
resultRow = 2
For row = 2 To UBound(data, 1)
For col = 3 To UBound(data, 2)
If data(row, col) = "x" Then
result(resultRow, 1) = data(row, 2) ' Value
result(resultRow, 2) = data(1, col) ' Caption (eg "frame 1")
result(resultRow, 3) = data(row, 1) ' Name
resultRow = resultRow + 1
End If
Next col
Next row
' write result
destRange.Resize(UBound(result, 1), 3) = result
End Sub
用这样的东西调用例程 - 根据您的需要调整工作表和范围:
Sub testx()
ConvertMyData ThisWorkbook.Sheets(1).Range("A1"), ThisWorkbook.Sheets(1).Range("G1")
End Sub
=LET(data,A1:E7,row_labels,{2;1},flag,"x",if_not_found,"",
rCols,COUNT(row_labels),
d,DROP(data,1),
rRows,ROWS(d),
rl,CHOOSECOLS(d,row_labels),
cl,DROP(TAKE(data,1),,rCols),
cCols,COLUMNS(cl),
cs,TOCOL(IF(SEQUENCE(rRows),cl)),
rs,CHOOSEROWS(rl,ROUNDUP(SEQUENCE(rRows*cCols)/cCols,)),
FILTER(HSTACK(cs,rs),TOCOL(DROP(d,,rCols))=flag,if_not_found))