问题描述
我基本上被困在这个 VBA 中,因为我不知道如何查找 2 个单元格并返回另一个单元格值。可能可以通过读取项目名称先查找然后读取周数以匹配并返回灰色区域中的相位来解决,但是将2查找放在一起对我来说很困难。
This is the first sheet where the input come in as week number and date in each phase
解决方法
使用几个 Dictionary Objects 作为对 Project 行和 Week 列的查找。
Option Explicit
Sub Macro()
Const SHT_PRJ = "Project"
Const COL_ID_PRJ = "E"
Const COL_PH1 = "F" ' Phase 1
Const ROW_HDR_PRJ = 2 ' header
Const SHT_DEM = "Demand"
Const COL_ID_DEM = "D"
Const ROW_HDR_DEM = 1
Const MAX_PH = 6 ' phases 1 to 6
Dim wb As Workbook
Dim wsIn As Worksheet,wsOut As Worksheet
Dim cell As Range,rng As Range
Dim iRow As Long,iLastRow As Long,iCol() As Integer,iLastCol As Integer
Dim iColWk As Integer
Dim iColor As Variant,sWk As String,iPh As Integer
Set wb = ThisWorkbook
Set wsIn = wb.Sheets(SHT_PRJ)
Dim dict As Object,dictWk As Object,key
Set dict = CreateObject("Scripting.Dictionary")
Set dictWk = CreateObject("Scripting.Dictionary")
' build lookup to row for ID
iLastRow = wsIn.Cells(Rows.Count,COL_ID_PRJ).End(xlUp).Row
For iRow = ROW_HDR_PRJ + 1 To iLastRow
key = Trim(wsIn.Cells(iRow,COL_ID_PRJ))
If dict.exists(key) Then
MsgBox "Duplicate key " & key,vbCritical,"Row " & iRow
Exit Sub
ElseIf Len(key) > 0 Then
dict.Add key,iRow
End If
Next
' build look up to column for week
Set wsOut = wb.Sheets(SHT_DEM)
iLastCol = wsOut.Cells(ROW_HDR_DEM,Columns.Count).End(xlToLeft).Column
For Each cell In wsOut.Cells(ROW_HDR_DEM,1).Resize(1,iLastCol)
key = Trim(cell.Value)
If dictWk.exists(key) Then
MsgBox "Duplicate week " & key,"Col " & cell.Column
Exit Sub
ElseIf Len(key) > 0 Then
dictWk.Add key,cell.Column
End If
Next
' update demand sheet
ReDim iCol(MAX_PH)
iLastRow = wsOut.Cells(Rows.Count,COL_ID_DEM).End(xlUp).Row
For Each cell In wsOut.Cells(ROW_HDR_DEM + 1,COL_ID_DEM).Resize(iLastRow)
iColor = cell.Interior.ColorIndex
key = Trim(cell.Value)
' each project
If Len(key) > 0 And iColor <> xlColorIndexNone Then '-4142
iRow = dict(key) ' row on project sheet
If iRow < 1 Then
MsgBox "ID " & key & " not found",_
wsOut.Name & " Row " & cell.Row
Exit Sub
Else
' get week numbers for each phase
For iPh = 1 To MAX_PH
sWk = wsIn.Cells(iRow,COL_PH1).Offset(0,2 * (iPh - 1))
If Len(sWk) > 0 Then
' look up week to column
iCol(iPh) = dictWk(sWk)
If iCol(iPh) < 1 Then
MsgBox "Week " & sWk & " not found",_
wsOut.Name & " Row " & cell.Row
Exit Sub
Else
' update sheet
wsOut.Cells(cell.Row,iCol(iPh)) = "Phase " & iPh
End If
End If
Next
' fill in gaps with previous
For iColWk = iCol(1) To iCol(MAX_PH)
Set rng = wsOut.Cells(cell.Row,iColWk)
If rng.Value = "" Then
rng.Value = rng.Offset(0,-1).Value
End If
Next
End If
End If
Next
MsgBox dict.Count & " projects processed"
End Sub