If 语句 INDEX/MATCH 匹配不同 sheet 中的两个值范围
If Statement with INDEX/MATCH to matched between two range of values in different sheet
我有从 1994 年到 2014 年的年份范围,并且对于范围内相应的公司名称值相互矛盾(输出 Sheet)。我使用这个公式(如下)从 Sheet1 得到各个公司每年的销售数字,输出 sheet.
来源Sheet/Sheet1
输出Sheet
=INDEX('Sheet1'!$E:$Y5,MATCH(Output!B2,'Sheet1'!$D:$D5,0),MATCH(Output!A2,'Sheet1'!$E:$Y,0))
我使用了两个匹配公式,因为我想验证公司名称和年份。
现在,我想检查我从上述等式中检索到的值是否与源值完全 match/True。因此,我尝试使用此公式,但尽管第一个 IF 逻辑为真,但第二个失败。
=IFS(Output!B2=INDEX('Sheet1'!$D:$D5,MATCH(Output!B2,'Sheet1'!$D:$D5,0)),"OK",C2=INDEX('Sheet1'!$E:$Y5,MATCH(Output!B2,'Sheet1'!$D:$D5,0),MATCH(Output!A2,'Sheet1'!$E:$Y,0)),"FINE")
我正在寻找手头整个任务的 VBA 代码,以防 VBA 使它更容易,因为我有庞大的数据集来执行相同的过程。
A VBA 逆轴
- 将代码复制到标准模块中,例如
Module1
包含两个工作表的工作簿。
- 仔细调整常量部分中的值。
- 两个单元格地址都引用 table headers.
的第一个单元格
- 你应该
PowerQuery
试试看。一旦你掌握了它,这将需要几分钟。它有很多选项。
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Unpivots a table range (has headers) to another worksheet.
' Calls: 'RefCurrentRegionBottomRight'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub UnPivotData()
' Source
Const sName As String = "Sheet1"
Const sFirstCellAddress As String = "D4"
Const scCount As Long = 22
' Destination
Const dName As String = "Output"
Const dFirstCellAddress As String = "A1"
Dim dHeaders As Variant: dHeaders = VBA.Array("YEAR", "COMPANY", "WC01651")
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Write from source range to source array.
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim sfCell As Range: Set sfCell = sws.Range(sFirstCellAddress)
Dim srg As Range
Set srg = RefCurrentRegionBottomRight(sfCell).Resize(, scCount)
Dim srCount As Long: srCount = srg.Rows.Count
Dim sData As Variant: sData = srg.Value
' Size destination array.
Dim dhUpper As Long: dhUpper = UBound(dHeaders)
Dim drCount As Long: drCount = (srCount - 1) * (scCount - 1) + 1
Dim dcCount As Long: dcCount = dhUpper + 1 ' zero- vs one-based
Dim dData As Variant: ReDim dData(1 To drCount, 1 To dcCount)
' Write headers.
Dim dh As Long
For dh = 0 To dhUpper
dData(1, dh + 1) = dHeaders(dh)
Next dh
Dim dr As Long: dr = 1 ' headers already written
Dim sr As Long
Dim sc As Long
' Write data ('body').
For sr = 2 To srCount
For sc = 2 To scCount
dr = dr + 1 ' Note the 'PowerQuery' terms in parentheses:
dData(dr, 1) = sData(1, sc) ' write column labels (attributes)
dData(dr, 2) = sData(sr, 1) ' write row labels
dData(dr, 3) = sData(sr, sc) ' write values (values)
Next sc
Next sr
' Write from destination array to destination range.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfCell As Range: Set dfCell = dws.Range(dFirstCellAddress)
Dim dcrg As Range
Set dcrg = dfCell.Resize(dws.Rows.Count - dfCell.Row + 1, dcCount)
dcrg.ClearContents
Dim drg As Range: Set drg = dfCell.Resize(drCount, dcCount)
drg.Value = dData
MsgBox "Data transferred.", vbInformation
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns a reference to the range starting with a given cell
' and ending with the last cell of its Current Region.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefCurrentRegionBottomRight( _
ByVal FirstCellRange As Range) _
As Range
If FirstCellRange Is Nothing Then Exit Function
With FirstCellRange.Cells(1).CurrentRegion
Set RefCurrentRegionBottomRight = _
FirstCellRange.Resize(.Row + .Rows.Count - FirstCellRange.Row, _
.Column + .Columns.Count - FirstCellRange.Column)
End With
End Function
我有从 1994 年到 2014 年的年份范围,并且对于范围内相应的公司名称值相互矛盾(输出 Sheet)。我使用这个公式(如下)从 Sheet1 得到各个公司每年的销售数字,输出 sheet.
来源Sheet/Sheet1
输出Sheet
=INDEX('Sheet1'!$E:$Y5,MATCH(Output!B2,'Sheet1'!$D:$D5,0),MATCH(Output!A2,'Sheet1'!$E:$Y,0))
我使用了两个匹配公式,因为我想验证公司名称和年份。
现在,我想检查我从上述等式中检索到的值是否与源值完全 match/True。因此,我尝试使用此公式,但尽管第一个 IF 逻辑为真,但第二个失败。
=IFS(Output!B2=INDEX('Sheet1'!$D:$D5,MATCH(Output!B2,'Sheet1'!$D:$D5,0)),"OK",C2=INDEX('Sheet1'!$E:$Y5,MATCH(Output!B2,'Sheet1'!$D:$D5,0),MATCH(Output!A2,'Sheet1'!$E:$Y,0)),"FINE")
我正在寻找手头整个任务的 VBA 代码,以防 VBA 使它更容易,因为我有庞大的数据集来执行相同的过程。
A VBA 逆轴
- 将代码复制到标准模块中,例如
Module1
包含两个工作表的工作簿。 - 仔细调整常量部分中的值。
- 两个单元格地址都引用 table headers. 的第一个单元格
- 你应该
PowerQuery
试试看。一旦你掌握了它,这将需要几分钟。它有很多选项。
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Unpivots a table range (has headers) to another worksheet.
' Calls: 'RefCurrentRegionBottomRight'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub UnPivotData()
' Source
Const sName As String = "Sheet1"
Const sFirstCellAddress As String = "D4"
Const scCount As Long = 22
' Destination
Const dName As String = "Output"
Const dFirstCellAddress As String = "A1"
Dim dHeaders As Variant: dHeaders = VBA.Array("YEAR", "COMPANY", "WC01651")
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Write from source range to source array.
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim sfCell As Range: Set sfCell = sws.Range(sFirstCellAddress)
Dim srg As Range
Set srg = RefCurrentRegionBottomRight(sfCell).Resize(, scCount)
Dim srCount As Long: srCount = srg.Rows.Count
Dim sData As Variant: sData = srg.Value
' Size destination array.
Dim dhUpper As Long: dhUpper = UBound(dHeaders)
Dim drCount As Long: drCount = (srCount - 1) * (scCount - 1) + 1
Dim dcCount As Long: dcCount = dhUpper + 1 ' zero- vs one-based
Dim dData As Variant: ReDim dData(1 To drCount, 1 To dcCount)
' Write headers.
Dim dh As Long
For dh = 0 To dhUpper
dData(1, dh + 1) = dHeaders(dh)
Next dh
Dim dr As Long: dr = 1 ' headers already written
Dim sr As Long
Dim sc As Long
' Write data ('body').
For sr = 2 To srCount
For sc = 2 To scCount
dr = dr + 1 ' Note the 'PowerQuery' terms in parentheses:
dData(dr, 1) = sData(1, sc) ' write column labels (attributes)
dData(dr, 2) = sData(sr, 1) ' write row labels
dData(dr, 3) = sData(sr, sc) ' write values (values)
Next sc
Next sr
' Write from destination array to destination range.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfCell As Range: Set dfCell = dws.Range(dFirstCellAddress)
Dim dcrg As Range
Set dcrg = dfCell.Resize(dws.Rows.Count - dfCell.Row + 1, dcCount)
dcrg.ClearContents
Dim drg As Range: Set drg = dfCell.Resize(drCount, dcCount)
drg.Value = dData
MsgBox "Data transferred.", vbInformation
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns a reference to the range starting with a given cell
' and ending with the last cell of its Current Region.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefCurrentRegionBottomRight( _
ByVal FirstCellRange As Range) _
As Range
If FirstCellRange Is Nothing Then Exit Function
With FirstCellRange.Cells(1).CurrentRegion
Set RefCurrentRegionBottomRight = _
FirstCellRange.Resize(.Row + .Rows.Count - FirstCellRange.Row, _
.Column + .Columns.Count - FirstCellRange.Column)
End With
End Function