我正在寻找类似的公式,如下所示: How to copy data from sheet1 to sheet2 with a condition in Excel
我正在使用:
= IF(EXACT(Sheet 1中!B4,Sheet 2中!A7),工作表Sheet!A4)
只是我想添加条件,如果sheet1的B列没有我要查找的值,它将查看B列中的下一行。如果匹配那么A列中该行的值将是复制的值。
由于
答案 0 :(得分:1)
很明显,没有人会为您提供配方解决方案。当然我不知道如何用公式解决你的问题。
您尚未定义来源或目标表格的格式。但是,我有一些代码可以解决,以匹配可能的格式。
下图中左侧是我的源表。请注意,列C包含一个我已格式化为“ddd dd”的日期,因为我发现这种类型的列表是一种方便的格式。右侧是输出的打印图像。列宽,边框和单元格合并由宏设置。
站名称序列由宏中的数组设置。我有三个站,但这是任意的。输出表中的开始日期,开始时间,结束时间和结束日期由源表中的最早和最新值设置。
宏中的原始验证与您的要求不符,因此我删除了它。您需要添加自己的。
宏观并未注意到安吉拉周二中午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
答案 1 :(得分:0)
以下示例可帮助您根据“来自工作表”中的匹配列,将值(行方式)从一个工作表复制到另一个工作表。
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