Перемещение значения с одного листа на другой

#excel #vba

Вопрос:

Извините, довольно общий вопрос, но не могу найти похожих вопросов, действительно дающих то, что мне нужно.

Мне нужно перенести дату с листа X на лист 7. На листе значение даты хранится в столбце C и объединяется по нескольким строкам, в которых на эту дату работает более 1 сотрудника. Сотрудники указаны в столбце E. Это значение в столбце E — «Имя, фамилия, отчество». Мне нужно скопировать дату с листа X на лист 7, где место, куда она должна попасть, находится в столбце P в строке, где идентификатор конкретного сотрудника находится в столбце C.

Весь этот процесс начинается с выбора ячейки «Имя-фамилия» на листе, а идентификаторы состоят из 7 чисел. Я смог настроить это достаточно, чтобы перестать получать какие-либо ошибки, но это не работает:

 Sub StartDateToDataSheet()
  Dim i, ActiveRow, DataRow, EmpID As Long, StartDate As Date
  EmpID = Left(ActiveCell.Value, 7)
  DataRow = Application.Match(EmpID, Sheet7.Range("C2:C699"), 0)
  ActiveRow = ActiveCell.Row
  For i = ActiveRow To 6 Step -1
    If Cells(i, 3) <> "" Then
      StartDate = Cells(i, 3)
      Exit For
    End If
  Next i
  Sheet7.Cells(DataRow, 16) = StartDate
End Sub
 

Тогда кое-что, что я еще не рассмотрел, — это небольшая обработка ошибок. Идентификатор всегда должен быть на листе 7, и у меня есть небольшой страх перед пробелом в начале «Имя и фамилия идентификатора».

Ответ №1:

Поиск в VBA с объединенными ячейками ( Find )

 Option Explicit

Sub StartDateToDataSheet()
' s - Source (SheetX) - only read from
' d - Destination (Sheet7) - read from and written to
' l - Lookup (ID)
' v - Value (Date)

    Const slFirst As String = "E2"
    Const svCol As String = "C"
    
    Const dlFirst As String = "C2"
    Const dvCol As String = "P"
    Const dvNotFound As Variant = "Nope"
  
    Dim sws As Worksheet: Set sws = SheetX
    Dim dws As Worksheet: Set dws = Sheet7
    
    Dim slrg As Range: Set slrg = RefColumn(sws.Range(slFirst))
    If slrg Is Nothing Then Exit Sub ' no data in source lookup column
    Dim sllCell As Range: Set sllCell = slrg.Cells(slrg.Cells.Count)
    
    Dim dlrg As Range: Set dlrg = RefColumn(dws.Range(dlFirst))
    If dlrg Is Nothing Then Exit Sub ' no data in destination lookup column
    
    'Debug.Print slrg.Address(0, 0), dlrg.Address(0, 0)
    
    Dim slCell As Range
    Dim svCell As Range
    Dim dlCell As Range
    Dim dvCell As Range
    
    For Each dlCell In dlrg.Cells
        Set slCell = slrg.Find(Trim(CStr(dlCell.Value)), _
            sllCell, xlFormulas, xlPart)
        Set dvCell = dlCell.EntireRow.Columns(dvCol)
        If slCell Is Nothing Then ' not found
            dvCell.Value = dvNotFound
        Else ' found
            Set svCell = slCell.EntireRow.Columns(svCol)
            If svCell.MergeCells Then ' merged
                dvCell.Value = svCell.MergeArea(1).Value
            Else ' not merged
                dvCell.Value = svCell.Value
            End If
        End If
    Next dlCell
    
End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Creates a reference to the one-column range from the first cell
'               of a range ('FirstCell') to the bottom-most non-empty cell
'               of the first cell's worksheet column.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefColumn( _
    ByVal FirstCell As Range) _
As Range
    If FirstCell Is Nothing Then Exit Function
    
    With FirstCell.Cells(1)
        Dim lCell As Range
        Set lCell = .Resize(.Worksheet.Rows.Count - .Row   1) _
            .Find("*", , xlFormulas, , , xlPrevious)
        If lCell Is Nothing Then Exit Function
        Set RefColumn = .Resize(lCell.Row - .Row   1)
    End With

End Function
 

Ответ №2:

Так что немного поиграл с этим. Добавление 1 к результату матча теперь дает мне правильную строку для листа 7. Использовал LTrim, чтобы избавиться от начальных пробелов, и добавил небольшую обработку ошибок, которая соответствует моим потребностям.

 Sub StartDateToDataSheet()
  On Error GoTo eh
  Dim i, DataRow, ActiveRow, EmpID As Long, StartDate As Date
  EmpID = Left(LTrim(ActiveCell.Value), 7)
  DataRow = Application.Match(EmpID, Sheet7.Range("C2:C699"), 0)   1
  ActiveRow = ActiveCell.Row
  For i = ActiveRow To 6 Step -1
    If Cells(i, 3) <> "" Then
      StartDate = Cells(i, 3)
      Exit For
    End If
  Next i
  Sheet7.Cells(DataRow, 16) = StartDate
Done:
  Exit Sub
eh:
  MsgBox "ID not found in data sheet"
End Sub