列内容匹配时,将值从一个表复制到另一个表

我正在寻找一个类似的公式,如下所示: 如何在Excel中使用条件将sheet1中的数据复制到sheet2

我在用:

= IF(EXACT(工作表Sheet1!B4,Sheet2的!A7),工作表Sheet1!A4)

我只想添加如下条件:如果sheet1的列B没有我正在查找的值,那么将查看B列中的下一行。如果匹配,那么列A中该行的值将是值复制。

谢谢

似乎很清楚,没有人会为您提供配方解决scheme。 当然,我不知道如何解决你的问题与公式。

您尚未定义来源或目标工作表的格式。 不过,我有一些代码,我可以破解匹配可能的格式。

下面的图片左侧是我的源表。 请注意,列C包含一个date,我格式化为“DDD DD”,因为我发现这种types的列表方便的格式。 在右边是输出的打印图像。 列的宽度,边框和单元格合并由macros设置。

站名的顺序由macros内的数组设定。 我有三个电台,但这是任意的。 输出表中的开始date,开始时间,结束时间和结束date由源表中的最早值和最新值设置。

macros中的原始validation与您的要求不符,所以我删除了它。 你将需要添加自己的。

macros观并没有注意到安吉拉星期二中午12点有两个电台。 它确实注意到,源行13和18覆盖了以前的条目并报告了这些错误。

在这里输入图像说明

下面的代码包含解释它在做什么的注释,但不包括为什么或如何。 我希望这给你一些想法。 如果有必要回来的问题。

Option Explicit Type typStationBooking NamePerson As String NameStation As String BookDate As Date BookTimeStart As Long ' Time in minutes 540 = 9:00 BookTimeEnd As Long ' Time in minutes 900 = 15:00 End Type Sub ListByNameToListByStation() Dim ColDataCrnt As Long Dim DateCrnt As Date Dim DateLatest As Date Dim DateEarliest As Date Dim Found As Boolean Dim InxBookCrnt As Long Dim InxBookMax As Long Dim InxStatCrnt As Long Dim NumRowsPerDay As Long Dim NumStations As Long Dim NumTimeSlots As Long Dim Occupied As Boolean Dim RowDataCrnt As Long Dim RowDataDayFirst As Long Dim RowDataLast As Long Dim RowDataTimeSlot As Long Dim StationBooking() As typStationBooking Dim StationName() As Variant Dim SheetDest As String Dim SheetSrc As String Dim TimeCrnt As Long Dim TimeEarliest As Long Dim TimeLatest As Long Dim TimeInterval As Long ' Names of stations in desired column sequence. Names must match ' those used in worksheet Source. LBound = 0 StationName = Array("Station2", "Station3", "Station1") SheetDest = "Dest" ' ) Change to your SheetSrc = "Source" ' ) sheet names DateEarliest = -1 DateLatest = -1 TimeInterval = 30 ' ) Values in minutes. Change as necessary TimeEarliest = -1 TimeLatest = -1 With Sheets(SheetSrc) ' First Last used row RowDataLast = .Cells(Rows.Count, "A").End(xlUp).Row ' Reserve space for rows 2 to RowLast ReDim StationBooking(1 To RowDataLast - 1) InxBookMax = 0 ' No current entries ' Load data from Sheet1 table into array For RowDataCrnt = 2 To RowDataLast ' ### The source data should be checked: ' * Person name non-blank ' * Station name matches value in StationName() ' * Day is date in range DateFirst to DateLast ' * Start and End times are times in range TimeFirst to ' TimeLast+TimeInteval with Start time before End time ' and both are of the form TimeStart + N*TimeInterval ' where is a positive integer InxBookMax = InxBookMax + 1 StationBooking(InxBookMax).NamePerson = .Cells(RowDataCrnt, 1).Value StationBooking(InxBookMax).NameStation = .Cells(RowDataCrnt, 2).Value StationBooking(InxBookMax).BookDate = .Cells(RowDataCrnt, 3).Value StationBooking(InxBookMax).BookTimeStart = _ Hour(.Cells(RowDataCrnt, 4).Value) * 60 + _ Minute(.Cells(RowDataCrnt, 4).Value) StationBooking(InxBookMax).BookTimeEnd = _ Hour(.Cells(RowDataCrnt, 5).Value) * 60 + _ Minute(.Cells(RowDataCrnt, 5).Value) If DateEarliest = -1 Then DateEarliest = StationBooking(InxBookMax).BookDate DateLatest = StationBooking(InxBookMax).BookDate Else If DateEarliest > StationBooking(InxBookMax).BookDate Then DateEarliest = StationBooking(InxBookMax).BookDate End If If DateLatest < StationBooking(InxBookMax).BookDate Then DateLatest = StationBooking(InxBookMax).BookDate End If End If If TimeEarliest = -1 Then TimeEarliest = StationBooking(InxBookMax).BookTimeStart TimeLatest = StationBooking(InxBookMax).BookTimeEnd Else If TimeEarliest > StationBooking(InxBookMax).BookTimeStart Then TimeEarliest = StationBooking(InxBookMax).BookTimeStart End If If TimeLatest < StationBooking(InxBookMax).BookTimeEnd Then TimeLatest = StationBooking(InxBookMax).BookTimeEnd End If End If Next End With With Sheets(SheetDest) ' Lay out destination sheet ' Format per day ' Row 1 : Date ' Row 2 : Station names ' Row 3+: One row per time interval from TimeEarliest to ' TimeLatest + TimeInteval ' Row N : Blank row ' Col 1 : Time ' Col 2+: Station name ' Delete current contents .Cells.EntireRow.Delete NumRowsPerDay = (TimeLatest - TimeEarliest) / TimeInterval + 3 NumStations = UBound(StationName) + 1 ' Set column widths .Columns(1).ColumnWidth = 6 For ColDataCrnt = 2 To NumStations + 1 .Columns(ColDataCrnt).ColumnWidth = 14 Next RowDataCrnt = 1 DateCrnt = DateEarliest Do While DateCrnt <= DateLatest RowDataDayFirst = RowDataCrnt .Range(.Cells(RowDataCrnt, 1), .Cells(RowDataCrnt, 1 + NumStations)).Merge With .Cells(RowDataCrnt, 1) .HorizontalAlignment = xlCenter .NumberFormat = "dddd d mmmm" .Value = DateCrnt End With RowDataCrnt = RowDataCrnt + 1 InxStatCrnt = 0 For ColDataCrnt = 2 To NumStations + 1 .Cells(RowDataCrnt, ColDataCrnt).Value = StationName(InxStatCrnt) InxStatCrnt = InxStatCrnt + 1 Next RowDataCrnt = RowDataCrnt + 1 TimeCrnt = TimeEarliest Do While TimeCrnt < TimeLatest With .Cells(RowDataCrnt, 1) .NumberFormat = "hh:mm" .Value = DateCrnt + TimeSerial(TimeCrnt \ 60, TimeCrnt Mod 60, 0) End With RowDataCrnt = RowDataCrnt + 1 TimeCrnt = TimeCrnt + TimeInterval Loop With .Range(.Cells(RowDataDayFirst, 1), _ .Cells(RowDataCrnt - 1, NumStations + 1)) With .Borders(xlEdgeLeft) .LineStyle = xlContinuous .Weight = xlThin .Color = RGB(192, 192, 192) End With With .Borders(xlEdgeTop) .LineStyle = xlContinuous .Weight = xlThin .Color = RGB(192, 192, 192) End With With .Borders(xlEdgeBottom) .LineStyle = xlContinuous .Weight = xlThin .Color = RGB(192, 192, 192) End With With .Borders(xlEdgeRight) .LineStyle = xlContinuous .Weight = xlThin .Color = RGB(192, 192, 192) End With With .Borders(xlInsideVertical) .LineStyle = xlContinuous .Weight = xlThin .Color = RGB(192, 192, 192) End With With .Borders(xlInsideHorizontal) .LineStyle = xlContinuous .Weight = xlThin .Color = RGB(192, 192, 192) End With End With RowDataCrnt = RowDataCrnt + 1 DateCrnt = DateSerial(Year(DateCrnt), Month(DateCrnt), Day(DateCrnt) + 1) Loop ' Now place each entry in StationBooking in the appropriate cell(s) For InxBookCrnt = 1 To InxBookMax 'Debug.Assert InxBookCrnt <> 17 DateCrnt = StationBooking(InxBookCrnt).BookDate RowDataDayFirst = (DateCrnt - DateEarliest) * NumRowsPerDay + 1 TimeCrnt = StationBooking(InxBookCrnt).BookTimeStart RowDataTimeSlot = RowDataDayFirst + 2 + _ (TimeCrnt - TimeEarliest) / TimeInterval NumTimeSlots = (StationBooking(InxBookCrnt).BookTimeEnd - TimeCrnt) _ / TimeInterval Found = False For InxStatCrnt = 0 To UBound(StationName) If StationBooking(InxBookCrnt).NameStation = _ StationName(InxStatCrnt) Then Found = True Exit For End If Next If Not Found Then MsgBox ("Row " & InxBookCrnt + 1 & " of worksheet " & SheetSrc & _ "contains an unknown station name") Else ColDataCrnt = InxStatCrnt + 2 ' Check space for this entry is not already occupied Occupied = False For RowDataCrnt = RowDataTimeSlot To RowDataTimeSlot + NumTimeSlots - 1 If .Cells(RowDataCrnt, ColDataCrnt) <> "" Then Occupied = True Exit For End If Next If Not Occupied Then If Range(.Cells(RowDataTimeSlot, ColDataCrnt), _ .Cells(RowDataTimeSlot + NumTimeSlots - 1, _ ColDataCrnt)).MergeCells Then Occupied = True End If End If If Occupied Then MsgBox ("Row " & InxBookCrnt + 1 & " of worksheet " & SheetSrc & _ " overlaps a previous entry") Else ' Entire slot is free .Cells(RowDataTimeSlot, ColDataCrnt).Value = _ StationBooking(InxBookCrnt).NamePerson If NumTimeSlots > 1 Then With .Range(.Cells(RowDataTimeSlot, ColDataCrnt), _ .Cells(RowDataTimeSlot + NumTimeSlots - 1, ColDataCrnt)) .Merge .WrapText = True .VerticalAlignment = xlCenter End With End If End If End If Next End With End Sub 

下面的示例可以帮助您根据“来自工作表”中的匹配列将值(行)从一个工作表复制到另一个工作表。

 Sub TodaysActions() Dim listSheetRange As Range 'Sheet to copy data From Dim listSheet As Worksheet 'Sheet to copy data To Dim actionSheet As Worksheet Set listSheetRange = Worksheets("List").UsedRange Set listSheet = Worksheets("List") Set actionSheet = Worksheets("Action") 'Clear the To Sheet actionSheet.UsedRange.Clear 'Row 1 of From Sheet contains the data to match 'Copy Header Row ie Row 2 of From Sheet listSheet.Rows(2).Copy Destination:=actionSheet.Rows(1) currentActionRow = 2 For i = 3 To listSheetRange.Rows.Count 'Comparision Condition If InStr(listSheetRange.Cells(i, 1), listSheetRange.Cells(1, 3)) Then listSheet.Rows(i).Copy Destination:=actionSheet.Rows(currentActionRow) currentActionRow = currentActionRow + 1 End If Next i 'hide any unwanted columns actionSheet.Columns(1).Hidden = 1 actionSheet.Activate End Sub