Каков "правильный" способ копирования-вставки данных в VBA?
вопрос скорее теоретического характера:
Каков "правильный" способ копирования-вставки данных в vba / excel-vba ?
Теперь, по крайней мере, насколько мне известно, эти три метода являются единственными доступными:-
(
Range
).Copy([Destination])
метод -
(
Worksheet
).Paste([Destination, Link])
метод - и (
Range
).PasteSpecial([Paste], [Operation], [SkipBlanks], [Transpose])
метод
Теперь, я провел свое исследование, это плюсы и минусы .Copy([Destination])
и еще ... .Paste([Destination, Link])
метод, по крайней мере те, что я могу придумать:
+
Плюсы:
- позволяет нам вставлять данные в то же выражение, что и копирование (читаемость кода, я думаю..?)
И:
-
минусы:
- ссылки на ячейки - это в комплекте не идут!
- форматирование и формулы могут быть испорчены
- Если диапазон перекрывается, он будет отображать подсказку, эффективно останавливая макрос мертвым на его треках (это огромный облом особенно если вы пытаетесь что-то автоматизировать)
- еще хуже, если вы нажмете
Cancel
на приглашение, оно выдастError
** (если не обработано)
На другой стороне монеты, .PasteSpecial()
+
плюсы:
PasteSpecial()
позволяет нам вставить определенную часть диапазона!- это позволяет нам указать, какой тип вставки мы хотим сделать
- имеет встроенные функции
skipBlanks
иtranspose
- не" так "
Error
-склонен!!!
И я изо всех сил пытался придумать что-нибудь, но:
-
минусы:
- немного больше символов для записи..?
Теперь, это заставляет меня поверить, что аргумент Destination
метода .Copy()
должен по существу игнорироваться и PasteSpecial()
должен всегда использоваться вместо этого.
Есть ли когда-нибудь случай, когда его использование было бы предпочтительнее, чем .PasteSpecial()
? Или PasteSpecial()
должно быть нормой для каждой операции копирования-вставки?
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