Найдите значение в одной таблице, скопировав данные в другой столбец из той же строки, а затем вставьте в другую таблицу

#excel #vba

#excel #vba

Вопрос:

Итак, у меня есть две таблицы. Одна таблица содержит большой список заданий / имен и т.д., А другая таблица, по сути, представляет собой «отслеживание заданий», в котором перечислены все задания и сроки их выполнения.

У меня есть определенные задания, которые я должен выполнять каждый месяц или квартал. В начале каждого месяца я должен просмотреть свой сохраненный список, скопировать все задания, помеченные как месяц / квартал, а затем вставить их в мой журнал отслеживания заданий. Минимум у нас около 110 в месяц, поэтому я пытаюсь автоматизировать это, поскольку в информации о задании ничего не меняется — только срок выполнения.

Что я хочу сделать, это проверить в моей таблице наличие любого задания, помеченного как «Ежемесячное», скопировать название задания из этой строки и вставить его в мой журнал отслеживания заданий.

Я намеренно делаю все это отдельно, используя инструкции If, поскольку я создам пользовательскую форму, которая позволит мне (и другим пользователям) установить флажок, чтобы решить, хотят ли они бронировать определенные задания, т. Е. Ежемесячно, ежеквартально, раз в два года и т.д.

Например, я хочу, чтобы код выполнял следующее:

 If Frequency In Job Table = "Monthly" Then

Copy the Job Name 

Paste the Job Name into Job Tracking table

End If
  

Что, по сути, создало бы этот результат:
Идеальный результат
Это код, который у меня есть на данный момент. Моя проблема в том, что это работает только для одного результата и не пропускает каждый результат.

 Sub Test_IF_MATCH()

Dim ProdWS As Worksheet
Dim ProdTBL As ListObject
Dim ProdVAL As ListColumn
Dim newRow As ListRow
Dim newCol As ListColumn
Dim ColNum As Long
Dim TargetTBL As ListObject
Dim TargetVAL As ListColumn
Dim TargetVAL_F As ListColumn

Dim TargetRange As Range
Dim curr As Range

Set ProdWS = ActiveWorkbook.Worksheets("TESTWS")       '#####Edit here for deployment
Set ProdTBL = ProdWS.ListObjects("TESTTBL")            '#####Edit here for deployment
Set ProdVAL = ProdTBL.ListColumns("ValToMove")         '#####Edit here for deployment
Set ProdVAL_CPY = ProdTBL.ListColumns("Frequency")     '#####Edit here for deployment

Set TargetTBL = ProdWS.ListObjects("TESTTBL2")         '#####Edit here for deployment
Set newRow = TargetTBL.ListRows.Add
Set newCol = TargetTBL.ListColumns("Frequency output") '#####Edit here for deployment
ColNum = newCol.Index


'########################## Variables ##########################'
Set TargetRange = ProdTBL.ListColumns("Frequency").DataBodyRange
FindByFrequency = "Monthly"
'###############################################################'

'############## Index match values ##############'

Dim LookUpWS As Worksheet
Dim LookupRNG As Range

Set LookUpWS = ActiveWorkbook.Worksheets("TESTWS")
Set LookupRNG = LookUpWS.ListObjects("TESTTBL").DataBodyRange

'## Match one

Dim M1_Search As Range
Dim Test_TBL As ListObject

Set Test_TBL = LookUpWS.ListObjects("TESTTBL")
Set M1_Search = Test_TBL.ListColumns("Frequency").DataBodyRange

MatchOne = Application.WorksheetFunction.Match(FindByFrequency, M1_Search, 0)

'## Match two

Dim M2_Search As Range
Set M2_Search = LookUpWS.Range("A1:C1")

MatchTwo = Application.WorksheetFunction.Match("Job name", M2_Search, 0)

'################################################'

For Each curr In TargetRange

    If curr.Value = FindByFrequency Then
        Result = Application.WorksheetFunction.Index(LookupRNG, MatchOne, MatchTwo)
            With newRow
                .Range(, ColNum) = Result
            End With
    End If

Next

End Sub
  

Кто-нибудь может помочь, пожалуйста? На этом мои размышления заканчиваются, и я исчерпал свои возможности в Google и методом проб / ошибок решил проблему!

Ответ №1:

Вот пример использования фильтра для захвата всех экземпляров из вашей таблицы, где столбец частоты = Ежемесячно:

 Sub tgr()

    Dim wsData As Worksheet
    Dim oData As ListObject
    Dim rMatch As Range
    Dim FindByFrequency As String
    Dim FilterCol As String

    Set wsData = ActiveWorkbook.Worksheets("TESTWS")
    Set oData = wsData.ListObjects("TESTTBL")
    FindByFrequency = "Monthly"
    FilterCol = "Frequency"

    With oData.Range
        .AutoFilter oData.ListColumns(FilterCol).Index, FindByFrequency, xlFilterValues
        On Error Resume Next    'Prevent error if no cells are found
        Set rMatch = .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible)
        On Error GoTo 0         'Remove On Error Resume Next condition
        .AutoFilter
    End With

    If Not rMatch Is Nothing Then
        rMatch.Copy
        wsData.Range("D2").PasteSpecial xlPasteValues
        Application.CutCopyMode = False
    End If

End Sub
  

Комментарии:

1. Привет. Большое спасибо за помощь, действительно ценю ваш подход к проблеме — я об этом не подумал! К сожалению, я не знаю, достаточно ли хорошо я объяснил себя во введении, поэтому приношу извинения за потраченное впустую время. Макросу нужно скопировать только соответствующую ячейку (что я легко исправил, просто добавив номер столбца к установленному rMatch.. строка. Однако моя проблема заключается в вставке этих значений в новую таблицу. Кажется, я не могу заставить его добавить нужное количество строк, а затем вставить данные. Я могу заставить его составлять одну строку, но не требуемое количество

Ответ №2:

Итак, основываясь на ответе Tigeravatar, мне удалось адаптировать код в соответствии с тем, что мне нужно.

Это было почти на месте, так что огромное, огроменное спасибо Tigeravatar за то, что нашли время — это искренне ценится. Иногда нам просто нужно увидеть проблему свежим взглядом, чтобы преодолеть ее, не так ли

Ниже приведен код, который я использовал. Теперь он копирует только название целевого задания (вместо всей таблицы) и вставляет его в новую таблицу, добавляя новую строку.

Я добавил несколько комментариев, чтобы объяснить, что я сделал, на случай, если это поможет кому-либо еще.

 Sub tgr()

Dim wsData As Worksheet
Dim oData As ListObject
Dim oTarget As ListObject
Dim rMatch As Range
Dim FindByFrequency As String
Dim FilterCol As String
Dim newRow As ListRow
Dim colIndex As Integer
Dim colName As ListColumn

Set wsData = ActiveWorkbook.Worksheets("Test")

'The source of all the main data to pull from.
Set oData = wsData.ListObjects("PRODUCT")

'Gets the column index number of the column name that we want a result from
Set colName = oData.ListColumns("Job name")
colIndex = colName.Index

'Sets the destination for the data
Set oTarget = wsData.ListObjects("TRACKER")

'Adds a new row to the destination table
Set newRow = oTarget.ListRows.Add(AlwaysInsert:=True)

'############### Variable here ###############'
FindByFrequency = "Monthly"
'#############################################'

FilterCol = "Frequency"

'Copies the data that matches the criteria
With oData.Range
    .AutoFilter oData.ListColumns(FilterCol).Index, FindByFrequency, xlFilterValues
    On Error Resume Next    'Prevent error if no cells are found
    Set rMatch = .Offset(1).Resize(.Rows.Count - 1, colIndex).SpecialCells(xlCellTypeVisible)
    On Error GoTo 0         'Remove On Error Resume Next condition
    .AutoFilter
End With

'Debug - not essential
Debug.Print "Add " amp; rMatch.Count amp; " rows"

'Starts to paste the values to destination
If Not rMatch Is Nothing Then
    rMatch.Copy
    'Creates a new row for each values copied and pastes as values to destination
    newRow.Range.PasteSpecial xlPasteValues
    Application.CutCopyMode = False
End If


End Sub