Каков "правильный" способ копирования-вставки данных в VBA?


вопрос скорее теоретического характера:

Каков "правильный" способ копирования-вставки данных в vba / excel-vba ?

Теперь, по крайней мере, насколько мне известно, эти три метода являются единственными доступными:
  1. (Range) .Copy([Destination]) метод
  2. (Worksheet) .Paste([Destination, Link]) метод
  3. и (Range) .PasteSpecial([Paste], [Operation], [SkipBlanks], [Transpose]) метод

Теперь, я провел свое исследование, это плюсы и минусы .Copy([Destination]) и еще ... .Paste([Destination, Link]) метод, по крайней мере те, что я могу придумать:

+ Плюсы:

  • позволяет нам вставлять данные в то же выражение, что и копирование (читаемость кода, я думаю..?)

И:

- минусы:

  • ссылки на ячейки - это в комплекте не идут!
  • форматирование и формулы могут быть испорчены
  • Если диапазон перекрывается, он будет отображать подсказку, эффективно останавливая макрос мертвым на его треках (это огромный облом особенно если вы пытаетесь что-то автоматизировать)
  • еще хуже, если вы нажмете Cancel на приглашение, оно выдаст Error** (если не обработано)

На другой стороне монеты, .PasteSpecial()

+ плюсы:

  • PasteSpecial() позволяет нам вставить определенную часть диапазона!
  • это позволяет нам указать, какой тип вставки мы хотим сделать
  • имеет встроенные функции skipBlanks и transpose
  • не" так " Error-склонен!!!

И я изо всех сил пытался придумать что-нибудь, но:

- минусы:

  • немного больше символов для записи..?

Теперь, это заставляет меня поверить, что аргумент Destination метода .Copy() должен по существу игнорироваться и PasteSpecial() должен всегда использоваться вместо этого.

Есть ли когда-нибудь случай, когда его использование было бы предпочтительнее, чем .PasteSpecial()? Или PasteSpecial() должно быть нормой для каждой операции копирования-вставки?

1 3

1 ответ:

Дело не в удобочитаемости и не в том, сколько символов вы набираете. Это о то, что вам нужно для достижения.

Другими словами, он абсолютно не субъективен и не основан на мнениях, как и почти все остальное в программировании...

#ItDepends.

Если вы используете Excel и копируете-вставляете ячейки вокруг, делаете ли вы Ctrl+C и Ctrl+V или использоватьспециальную пасту ?

Зависит от того, что вам нужно делать.

  • Если вы хотите скопировать ячейку, ее значение, форматы, проверки данных, границы и т. д.; тогда .Paste [Destination] - Ваш лучший друг. Это программный эквивалент Ctrl+С/Ctrl+V ... Эквивалентно PasteSpecial / All, что является излишним, так как .Paste [Destination] уже делает все, что вам нужно сделать в этом случае.

    ссылки на ячейки-это полный отказ!

    Безусловно. Жестко закодированные ссылки на ячейки это плохо. .Paste [Destination] не заставляет вас делать это в любом случае, так что вопрос спорный.

    Если диапазон перекрывается, он покажет подсказку, эффективно останавливая макрос мертвым в его треках

    Диапазоны копирования и вставки не могут перекрываться, точка. Вы также получите это приглашение через .PasteSpecial.

  • Если вы хотите скопировать клетку Value, но не {71]} его форматы, валидации данных, границы и т. д.; тогда .PasteSpecial определенно лучшая идея, так как это программный эквивалент перехода вставить специальные / значения - за исключением того, что, вероятно, более эффективно просто назначить ячейку Value с тем, что вы хотите (нет необходимости туда и обратно в буфер обмена); OTOH если Вы действительно хотите вставить форматы, или проверки данных, или что-то еще, то это, вероятно, самый простой способ.

Paste не" портит " форматы. Он делает именно то, что должен делать. Paste и PasteSpecial являются не эквивалентами. Используйте правильный инструмент для работа. Они буквально являются программными эквивалентами "paste" и "paste special" соответственно - если вы находитесь в Excel и систематически переходите на "paste special", вы получите свой материал. Но каждый раз, когда вы делаете это, чтобы "вставить все", вы работаете больше, чем нужно.

PasteSpecial выглядит как хороший молоток, но не все является гвоздем. Когда вы можете избежать записи в буфер обмена, это, как правило, хорошая идея, чтобы избежать его... но опять же, если вы имеете дело с огромными наборами данных (подумайте 100K + ячеек), возможно, что он работает лучше, чем просто присваивание значений.

Это означало:

@ScottCraner я действительно думал об этом, но это не совсем копирование-вставка, а скорее типичная ссылка на указатель, поэтому я решил не включать его в свой вопрос. Я не хотел открывать книгу для обсуждения "что считается копипастингом".

Это неправильно. .Range(foo).Value = .Range(bar).Value - это не "типичная ссылка на указатель". Это буквально принятие ценностей foo в массив 2D variant и сбрасывает этот массив 2D variant на bar, перезаписывая ранее удерживаемые значения. Таким образом, это абсолютно правильная альтернатива попаданию в буфер обмена - но вам нужно будет протестировать и сравнить с Copy+PasteSpecial чтобы узнать, является ли это лучшим (/наиболее эффективным) решением для вашей ситуации:
Testing with 1500000 cells (100000 rows)
Pasting from clipboard, single operation: 324.21875ms
Setting cell values, single operation:    1496.09375ms


Testing with 150 cells (10 rows)
Pasting from clipboard, single operation: 11.71875ms
Setting cell values, single operation:    3.90625ms
Pasting from clipboard, iterative:        1773.4375ms
Setting cell values, iterative:           105.46875ms