Excel – 横跨和下来匹配

我有一张工作簿,里面有两张纸,第一张看起来像这样:

-------------------------------------------------------- Last Name | First Name | 1-Jan | 2-Jan | 3-Jan | 4-Jan | (continues on like this) -------------------------------------------------------- SMITH | John | 1 | 1 | | | -------------------------------------------------------- BOND | James | | | 1 | 1 | -------------------------------------------------------- 

第二张

  -------------------------------------------------------- | January | February | (continues on etc) -------------------------------------------------------- Last Name | First Name | From | To | From | To | -------------------------------------------------------- SMITH | John |1/1/18 | 2/2/18| | | -------------------------------------------------------- BOND | James |3/1/18 |4/1/18 | | | -------------------------------------------------------- 

这是一张休假表,基本上用户在他们正在休假的那一天在第一张纸上input“1”。 然后在第二张表中自动更新,以反映每个月的包含date。

因此,在第一个示例中,用户在1月1日和2月1日input1,这将更新第二张工作表,该工作人员将从1/1/18更改为2/1/18。

到目前为止,我成功地能够检测到一个1进入它抓住名称和date的细节,我一直在使用msgbox来validation我得到正确的数据。

我遇到的问题是,只要我能得到,我不能找出如何search第二张表来finddate和相应地更新。

  Private Sub Worksheet_Change(ByVal Target As Range) Dim KeyCells As Range ' The variable KeyCells contains the cells that will ' cause an alert when they are changed. Set KeyCells = Range("D6:OI53") If Not Application.Intersect(KeyCells, Range(Target.Address)) _ Is Nothing Then ' If cell changed, do the below ' ' Get name ' Dim lastName As String Dim firstName As String lastName = ActiveSheet.Cells(Target.Cells.Row, 1).Value firstName = ActiveSheet.Cells(Target.Cells.Row, 2).Value 'Get date ' Dim leaveDate As String leaveDate = ActiveSheet.Cells(5, Target.Cells.Column).Value ' Test lastname, firstname, date ' UpdateMonthlyLeave lastName, firstName, leaveDate End If End Sub Sub UpdateMonthlyLeave(lastName As String, firstName As String, leaveDate As String) MsgBox lastName & " " & firstName & " " & leaveDate ' Find employee on monthly leave sheet ' End Sub 

这个UDF将返回一个开始OR结束date的列表。 只是让你select表2中的列Wrap文本。我认为一个优点可能是Excel只会更新具有公式的单元格,如果它指定的范围发生了变化。

也许代码可以进一步简化,但不幸的是,你将不得不为sheet2中的每个单元格input公式。

 Option Explicit ' ShowStartMonth: True If we need to return the start date of the holidays ' MonthRange: The WHOLE Column range of the Month ' RowRange: The Range of the person's row but only the holiday columns, not the name columns ' MonthNameRow: The entire row of where the Month name is Public Function GetHoliday(ShowStartMonth As Boolean, iMonth As Integer, RowRange As Range, MonthNameRow As Range) As String Dim MonthRange As Range Set MonthRange = GetMonthRange(iMonth, MonthNameRow) 'Init variables ' Get the cells for the current month Dim rRow As Range Set rRow = Intersect(RowRange, RowRange.Worksheet.UsedRange, MonthRange) Dim IsCurrentCellHoliday As Boolean Dim IsLastCellHoliday As Boolean Dim IsStartHolidayContinuation As Boolean ' If First Day of month is a holiday and last day of last month is a holiday then ' Holiday is continuation IsStartHolidayContinuation = (rRow.Cells(1).Value = 1) And (rRow.Cells(1).Offset(0, -1).Value = 1) IsLastCellHoliday = (rRow.Cells(1).Value = 1) ' These will hold the dates for start or end of a holiday Dim StartDays() As String Dim EndDays() As String ReDim StartDays(0 To 255) ReDim EndDays(0 To 255) Dim SDIndex As Integer ' Index of the start day array Dim EDIndex As Integer ' Index of the end day array ' If Start of month is start of a new holiday then set it If (IsLastCellHoliday And Not IsStartHolidayContinuation) Then StartDays(0) = GetMonthName(rRow.Cells(1), MonthNameRow) ' If start of month is a holiday then set index to the second "StartHoliday" line SDIndex = IIf(IsStartHolidayContinuation Or IsLastCellHoliday, 1, 0) ' Keep first row Empty if start of month is holiday EDIndex = 0 ' Loop through all cells in the month for the person Dim i As Integer For i = SDIndex + 1 To rRow.Columns.Count Dim rCell As Range Set rCell = rRow.Cells(i) IsCurrentCellHoliday = rCell.Value = 1 'Check if current cell is a holiday ' If the current cell is different to the last cell then we need to do something If IsCurrentCellHoliday <> IsLastCellHoliday Then If IsCurrentCellHoliday Then StartDays(SDIndex) = GetMonthName(rCell, MonthNameRow) SDIndex = SDIndex + 1 ' Check if the first day of the next month is a holiday, if not then today is the last day If rCell.Column = MonthRange.Columns(MonthRange.Columns.Count).Column And rCell.Offset(0, 1).Value <> 1 Then EndDays(EDIndex) = GetMonthName(rRow.Cells(i), MonthNameRow) EDIndex = EDIndex + 1 End If Else EndDays(EDIndex) = GetMonthName(rRow.Cells(i - 1), MonthNameRow) EDIndex = EDIndex + 1 End If End If IsLastCellHoliday = IsCurrentCellHoliday Next Dim ReturnStrings() As String Dim ReturnIndex As Integer If (ShowStartMonth) Then ReturnStrings = StartDays ReturnIndex = SDIndex Else ReturnStrings = EndDays ReturnIndex = EDIndex End If Dim returnString As String returnString = IIf(Len(ReturnStrings(0)) = 0, " - ", ReturnStrings(0)) Dim j As Integer For j = LBound(ReturnStrings) + 1 To ReturnIndex - 1 returnString = returnString & vbNewLine & ReturnStrings(j) Next GetHoliday = returnString End Function Private Function GetMonthName(cell As Range, MonthRow As Range) As String Dim rMonth As Range Set rMonth = Intersect(cell.EntireColumn, MonthRow.EntireRow) End Function Public Function GetMonthRange(iMonth As Integer, MonthNameRow As Range) As Range Set MonthNameRow = Intersect(MonthNameRow.EntireRow, MonthNameRow.Worksheet.UsedRange) Dim startCell As Range Dim endCell As Range Dim rCell As Range For Each rCell In MonthNameRow.Cells If IsDate(rCell.Value) Then If month(CDate(rCell.Value)) = iMonth Then If startCell Is Nothing Then Set startCell = rCell ElseIf rCell.Column < startCell.Column Then Set startCell = rCell End If If endCell Is Nothing Then Set endCell = rCell ElseIf rCell.Column > endCell.Column Then Set endCell = rCell End If End If End If Next Set GetMonthRange = Range(startCell.Address & ":" & endCell.Address).EntireColumn Dim sAddress As String sAddress = GetMonthRange.Address End Function