2012-02-28 52 views
1

我寻找类似的公式,如下: How to copy data from sheet1 to sheet2 with a condition in Excel从一个片复制值到另一个时列内容匹配

我使用:

= IF(EXACT(Sheet 1中B4,Sheet 2中! A7),Sheet1!A4)

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

谢谢

+0

寻找公式中的“下一行”是不可能的,除非你使用数组公式,这有点棘手。因此,请向我们解释预期产出并向我们描述您的投入,以便我们能够帮助您。顺便说一下,如果你不介意,这种问题也可以用VBA轻松处理。 – JMax 2012-02-28 16:04:01

+0

感谢您的快速响应。 这是复制电台(1-16上午和下午)的一周。时间表上的每个人站将被复制到具有“当日队伍阵容”的第二张纸上 在表1上,每个人的姓名按字母顺序列出,每周他们被分配一周的电台。 在工作表2上,工作站按照上午和下午的数字排列。人员名称必须填写在他们在工作表1上分配的工作站旁边。 我想自动将日程安排复制到团队工作表中(工作表2) – MikeT 2012-02-28 16:50:04

+0

您可以使用问题左下角的链接编辑您的问题,以添加问题中的所有元素。您能否显示一个数据样本(链接到isntance的截图)? – JMax 2012-02-28 20:12:59

回答

1

看来很清楚,没有人会为您提供配方解决方案。当然,我不知道如何用公式解决你的问题。

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

下方图像的左侧是我的源表单。请注意,列C包含一个日期,我已格式化为“ddd dd”,因为我发现这种类型的列表方便的格式。在右边是输出的打印图像。列的宽度,边框和单元格合并由宏设置。

站名的序列由宏内的数组设置。我有三个站,但这是任意的。输出表中的开始日期,开始时间,结束时间和结束日期由源表中的最早和最新值设置。

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

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

enter image description here

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

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 
+0

很好的解决方案:)(和+1) – JMax 2012-03-01 13:12:21

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 
相关问题