#excel #vba
Вопрос:
Я довольно долго борюсь с возможными решениями, но я не смог найти что-то подобное в Интернете, и мне не помешала бы помощь. Пример снимка экрана и пример книги в ссылках, о которых идет речь. Я задавал один и тот же вопрос на другом форуме, но ответов не было… https://www.mrexcel.com/board/threads/find-copy-insert-row-on-condition-with-cell-merge-and-formula-copy.1178634/
У меня есть 3 рабочих листа, ForDelivery
, Document1
и Document2
. С листов документов, которые я распечатываю на первой странице или отправляю по электронной почте, я хочу заполнить определенные ячейки на листах документов 1 и 2 ( range"G19:K"
) значениями с ForDelivery
листов (значения находятся в диапазоне "B2:F"
.
В листах Document1
и Document2
у меня есть шаблон таблицы, столбец «Б» в обеих таблицах содержат названия продуктов, мне нужен макрос, который будет искать эти имена в лист ForDelivery
и в случае, если имя находится в столбце "A"
а затем скопировать все значения из диапазона "B:F"
от строки, где имя было найдено в строке листа, где имя столбца диапазона "G:K"
. Я собираюсь выполнить эту работу, XLOOKUP fuction
НО проблема возникает, когда в столбце указано более одного названия продукта "A"
(число может варьироваться от 2 до 8). Эта функция не справляется, но я надеюсь, что макрос справится. Поэтому для каждого одного и того же имени мне нужно вставить новую строку под исходной строкой, скопировать форумы сверху и вставить значения в диапазон "G:K"
. Я создал код, который будет объединять ячейки в столбцах A
B
, и F
, чтобы предотвратить дублирование значений. Таким образом, в принципе, если в столбце листа есть 3 одинаковых имени "A"
ForDelivery
, вставьте 2 строки (2, потому что уже существует одна строка) в Document 1 or 2
лист, где найдено имя, и вставьте данные из диапазона B:F
в диапазон G:K
. Заранее спасибо.
Скриншот: https://ibb.co/sFh5dRY Образец рабочей тетради здесь: https://easyupload.io/4f7cq2
Если это полезно, вот код, который я использую для объединения ячеек в столбцах
Sub macro1()
Dim lngLastRow As String
Dim lastRow As Long
Dim lastcolumn As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
lastRow = ActiveSheet.UsedRange.Row - 1 ActiveSheet.UsedRange.Rows.Count
lastcolumn = ActiveSheet.UsedRange.Column - 1 ActiveSheet.UsedRange.Columns.Count
ActiveSheet.Sort.SortFields.Clear
ActiveSheet.Sort.SortFields.Add Key:=Range(Cells(19, 1), Cells(lastRow, 1)), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveSheet.Sort
.SetRange Range(Cells(19, 1), Cells(lastRow, lastcolumn))
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
For i = lastRow To 19 Step -1
If Cells(i, 1).Value = Cells(i - 1, 1).Value Then
Range(Cells(i, 1), Cells(i - 1, 1)).Select
Selection.Merge
Range(Cells(i, 2), Cells(i - 1, 2)).Select
Selection.Merge
Range(Cells(i, 3), Cells(i - 1, 3)).Select
Selection.Merge
Range(Cells(i, 6), Cells(i - 1, 6)).Select
Selection.Merge
End If
Next
Application.ScreenUpdating = True
End Sub
Ответ №1:
Вы можете попробовать этот код, я добавил комментарии, чтобы вы могли иметь представление о том, что происходит. Кодовое имя дается внутри VBA для любого листа, они хороши, если ваши листы никто не удалит. Если нет, измените их на имена ваших листов, как обычно.
Примечание: Я не могу видеть комментарии в другом цвете в предварительном просмотре. Кроме того, не проверял часть формулы. Извините, если я что-то пропустил.
Public Sub Populate_Document1()
Dim i As Long, no_item_doc1 As Long, currentrow_doc1 As Long
Dim rngDelivery As Range
Dim cCell_Doc1 As Range
Dim cCell_Delivery As Range
Dim rngDoc1 As Range
Dim arrDoc1 As Variant
Dim lastrow_doc1 As Long
' Find last row of Document1 (Codename set as doc1 in VBA Editor)
' doc1 = sheets("Document1")
' delivery = sheets("ForDelivery")
lastrow_doc1 = doc1.Cells(18, 2).End(xlDown).Row
Set rngDoc1 = doc1.Range("B19:B" amp; lastrow_doc1)
' Assign rngDoc1 values to an array arrDoc1
ReDim arrDoc1(1 To rngDoc1.Rows.Count, 1 To 1) As String
arrDoc1 = rngDoc1.Value ' arrays normally start with index 0, but 1 if we assign from a range
' Set rngDelivery to items list on ForDelivery Sheet
' Can be done in one line, but easier to read like this
Set rngDelivery = delivery.Range("A1").CurrentRegion
Set rngDelivery = rngDelivery.Offset(1, 0).Resize(rngDelivery.Rows.Count - 1, 1)
currentrow_doc1 = 19 ' will update this if we insert any lines due to duplicates
For i = 19 To lastrow_doc1
no_item_doc1 = 0 ' reset to 0, number of items found on delivery sheet for the item in question in doc1
For Each cCell_Delivery In rngDelivery
If cCell_Delivery.Value = arrDoc1(i - 18, 1) Then
If no_item_doc1 = 0 Then
no_item_doc1 = 1
cCell_Delivery.Offset(0, 1).Resize(1, 5).Copy doc1.Range("G" amp; currentrow_doc1)
Else
' increase currentrow since a duplicate is found
currentrow_doc1 = currentrow_doc1 1
' Insert a row
doc1.Rows(currentrow_doc1).Insert
' copy the B-F columns from delivery sheet
cCell_Delivery.Offset(0, 1).Resize(1, 5).Copy doc1.Range("G" amp; currentrow_doc1)
' copy A-F columns of duplicate item from 1 row above
doc1.Range("A" amp; currentrow_doc1 - 1 amp; ":F" amp; currentrow_doc1 - 1).Copy doc1.Range("A" amp; currentrow_doc1 amp; ":F" amp; currentrow_doc1)
' copy the formulas from 1 row above
doc1.Range("D" amp; currentrow_doc1 - 1 amp; ":E" amp; currentrow_doc1 - 1).Copy
doc1.Range("D" amp; currentrow_doc1 amp; ":E" amp; currentrow_doc1).PasteSpecial Paste:=xlPasteFormulasAndNumberFormats
' set font color to easily distinguish duplicates, can remove later if you want
doc1.Range("A" amp; currentrow_doc1 amp; ":F" amp; currentrow_doc1).Font.Color = rgbRed
End If
End If
Next cCell_Delivery
' increase currentrow by 1 since we are moving on to the next item on doc1
currentrow_doc1 = currentrow_doc1 1
Next i
' clean up set objects, not necessary here but good practice
Set rngDoc1 = Nothing
Set rngDelivery = Nothing
End Sub
Комментарии:
1. Извините за поздний ответ. код работает идеально. Я только что объявил рабочие листы и продублировал код для document2. Отличная работа, парень, я твой должник. Но я только что заметил во время тестирования, что есть небольшая проблема, мне было бы еще лучше, если бы мой код можно было скорректировать, скопировав некоторые другие формулы в строках. Я создал этот шаблон, чтобы сдвигать формулы вниз во время копирования и вставки новой строки. Другие формулы находятся в диапазоне для каждой строки, где имена находятся в диапазоне столбцов «O:AF». Могу ли я добавить строки в код, аналогичный исходной копии формулы, в столбцах D и E?
2. Я не могу понять, что именно вы имеете в виду. Содержатся ли эти формулы в исходном образце рабочей книги? Однако вы можете многое сделать, мне просто нужно точно знать, что нужно. Вы, конечно, можете ввести формулу для ячейки/диапазона ячеек, используя VBA. Или скопируйте откуда-нибудь еще, если нужно.
3. Вот ссылка на полный документ с вашим модулем, а некоторые мои, которые я создал, находятся в рабочей книге easyupload.io/skxfgi Извините, что не поместил все это в первый образец… я думал, что это не понадобится… когда вы копируете, например, строку 20 и вставляете ее в строку 21, формулы из этой строки в столбцах D и E в документе и в таблице справа от документа перемещаются в новую строку, чтобы функция sum могла работать…
4. Скриншот: ibb.co/DtpXv2H Пояснение: формулу из «O19» нужно скопировать в новую строку на картинке в O20 (формула в ячейке O19 равна (=D19) и так далее до фамилии в столбце B. мне нужны эти формулы для подсчета количества коробок для каждого продукта, когда я вставляю новую строку. Я не знаю другого пути… Есть какие-нибудь идеи?
5. Также извините за поздний ответ. Я устал за последние два дня. Давайте начнем с примера. Для пункта «1» (строка 19). Какими бы вы хотели видеть формулы? Включите оба диапазона (D:E) и O . Если формулы в D:E верны для добавленного элемента (второй «1») в строке 20, вам просто нужно скопировать формулы так же, как мы сделали для D:E. Кроме того, что произойдет, если вы запустите макрос во второй раз, скажем, по ошибке? Это будет полный бардак 🙂