繁体   English   中英

列内容匹配时,将值从一张纸复制到另一张纸

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM