[英]Copy values from one sheet to another when column contents match
我正在寻找一个类似的公式,如下所示: 如何在Excel中使用条件将数据从sheet1复制到sheet2
我在用:
= IF(EXACT(Sheet1!B4,Sheet2!A7),Sheet1!A4)
我只想添加以下条件:如果sheet1的B列没有我要查找的值,它将查看B列的下一行。如果匹配,则A列中的该行的值将是值已复制。
谢谢
似乎没有人会为您提供公式解决方案。 当然,我不知道如何用公式解决您的问题。
您尚未定义源表或目标表的格式。 但是,我有一些代码可以破解以匹配可能的格式。
下图的左侧是我的原始资料。 请注意,列C包含一个日期,我将其格式设置为“ ddd dd”,因为我发现该类型列表的便捷格式。 右边是输出的打印图像。 列宽,边框和单元格合并由宏设置。
站名的顺序由宏中的数组设置。 我有三个车站,但这是任意的。 输出表中的开始日期,开始时间,结束时间和结束日期由源表中的最早和最新值设置。
宏中的原始验证不符合您的要求,因此已将其删除。 您将需要添加自己的。
宏没有注意到安吉拉在星期二的12:00有两个电台。 它确实注意到源行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 i.e 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.