2012-02-28 48 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 
相關問題