Копирование данных в соответствующие поля на другом листе

#excel #vba #slowdown

#excel #vba #замедление

Вопрос:

введите описание изображения здесь
введите описание изображения здесь Я пытаюсь скопировать данные с отображаемого листа в соответствующий потребитель # в листе счетов, содержащий (176000) строк, следующий код, который я нашел, работает, но он очень медленный, для выполнения одной записи требуется около 5 минут.

 Sub SAVERECOVERY()

    For i = 5 To 125
        If Cells(i, 20) > 0 Then
           Sheets("Bills").Cells(Cells(i, 20), 24) = Sheets("Display").Cells(i, 5)
           Sheets("Bills").Cells(Cells(i, 20), 25) = Sheets("Display").Cells(i, 7)
           Sheets("Bills").Cells(Cells(i, 20), 26) = Sheets("Display").Cells(i, 9)
           Sheets("Bills").Cells(Cells(i, 20), 27) = Sheets("Display").Cells(i, 11)
        End If
    Next
End Sub
  

Отобразить лист:
Отображение

Ведомость счетов: Счета

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

1. Для передачи больших объемов данных используйте массив, создайте массив со всеми необходимыми данными, а затем вставьте сразу (таким образом, вы работаете с Excel только 2 или 3 раза вместо 176k)

2. Но вы не добавляете данные, вы изменяете их, как я вижу в коде, вы проверяете, больше ли ячейки в столбце 20 0, если да, то вы меняете ту же строку из счетов, что и на дисплее? Это ваша цель?

3. да, дорогая, это именно то, что я хочу сделать, у меня около 175000 строк в счетах, где доступны данные счетов потребителей, и теперь мне нужно изменить один сегмент счета потребителя, для которого я разработал таблицу отображения,

4. Но давайте предположим, что у одного потребителя есть 3 отдельные строки данных. На вашем листе отображения у этого потребителя также есть 3 строки данных или только одна? Потому что, если это позже, вы даете ему только последнюю запись из листа счетов.

5. уважаемый, на листе отображения отображается только один потребитель с ежемесячными счетами одного и того же потребителя за 2012 год, содержащими около 125 строк данных, поэтому теперь я редактирую эти счета на листе отображения и хочу, чтобы отредактированные данные были сохранены в листе счетов против уже существующих данных того же потребителя.

Ответ №1:

Попробуйте следующий код, пожалуйста. Это должно быть очень быстро. Необходимо только задать строки, в которые будут копироваться диапазоны ( firstRow , lastRow ), и позаботиться о том, чтобы в столбце 20 были (последовательные) строки, в которые будет вставлен результат обработки. Фактически, было бы достаточно записать только первую строку:

 Sub SAVERECOVERY()
 Dim firstRow As Long, lastRow As Long, shB As Worksheet, shD As Worksheet
 Dim arr24 As Variant, arr25 As Variant, arr26 As Variant, arr27 As Variant
 Dim pasteRow As Long, i As Long, arrRows As Variant
 
 Set shB = Sheets("Bills")
 Set shD = Sheets("Display")
 firstRow = 5: lastRow = 125: pasteRow = CLng(shD.cells(firstRow, 20))

 arr24 = shD.Range(shD.cells(firstRow, 5), shD.cells(lastRow, 5)).value
 arr25 = shD.Range(shD.cells(firstRow, 7), shD.cells(lastRow, 7)).value
 arr26 = shD.Range(shD.cells(firstRow, 9), shD.cells(lastRow, 9)).value
 arr27 = shD.Range(shD.cells(firstRow, 11), shD.cells(lastRow, 11)).value
 arrRows = shD.Range(shD.cells(firstRow, 20), shD.cells(lastRow, 20)).value
 
 Application.Calculation = xlCalculationManual
  For i = 1 To UBound(arrRows)
    If arr24(i, 1) <> "" Then shB.cells(CLng(arrRows(i, 1)), 24).value = arr24(i, 1)
    If arr25(i, 1) <> "" Then shB.cells(CLng(arrRows(i, 1)), 25).value = arr25(i, 1)
    If arr26(i, 1) <> "" Then shB.cells(CLng(arrRows(i, 1)), 26).value = arr26(i, 1)
    If arr27(i, 1) <> "" Then shB.cells(CLng(arrRows(i, 1)), 27).value = arr27(i, 1)
  Next i
  Application.Calculation = xlCalculationAutomatic
  
 shB.Activate: shB.cells(pasteRow, 24).Select
 MsgBox "Ready..."
End Sub
  

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

1. спасибо, дорогой, это работает, но единственная проблема в том, что он должен копировать только данные в заполненные ячейки, например, если ячейки от b4 до b134 на листе отображения имеют пустые ячейки, он не должен копировать данные из этого столбца строк 5,7,9,11. но ваш код копирует значения там, где этого не должно быть. я прикрепил новые изображения, пожалуйста, проверьте и заранее спасибо, короче говоря, как в вашем коде, последняя строка должна быть пустой строкой на листах отображения с b5 по b130.

2. @rohail nisar: Хорошо. Сейчас нет времени смотреть на код. Я сделаю это примерно через два часа… Но перед этим вы должны прояснить некоторые аспекты: Если нам нужно обработать 125 строк, как в вашем вопросе, и только 5 таких строк не являются пустыми, будут ли вставлены только они? Я имею в виду, что промежуточные строки на листе «Счета» уже содержат данные и не должны быть перезаписаны? Тогда возможно ли, чтобы в одном столбце (из 5, 7, 9, 11) строка не была пустой, а в других столбцах была пустой? Я имею в виду, что для обработки всех столбцов будет достаточно одной проверки на пустоту или нет?

3. @rohail nisar: Попробуйте обновленный код, пожалуйста. Он проверит каждый столбец на наличие пустых ячеек и скопирует только непустые. Пожалуйста, также отправьте отзыв. Я не проверял это, но это должно сработать. Я должен на некоторое время покинуть офис. Если это будет работать так, как вам нужно, мы здесь голосуем за код ответа и, что более важно, мы устанавливаем флажок слева от кода, чтобы сделать его принятым ответом . Таким образом, кто-то другой, ищущий что-то подобное, будет знать, что код работает…