Excel VBA: обход буфера обмена при копировании значений - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь скопировать информацию из одного файла в другой.Как читается здесь , есть более и менее эффективные способы сделать это.

В настоящее время я использую менее эффективный метод:

Target_Sheet.Cells.Copy
ThisWorkbook.Sheets("Name").Range("A1").PasteSpecial Paste:=xlPasteValues, _
        Operation:=xlNone, SkipBlanks:=False, Transpose:=False

Это работает в моем Excel (2016, 64-разрядная версия), но на некоторых компьютерах возникает ошибка нехватки памяти.Однако, когда я попробовал следующее утверждение, я сразу же получил ошибку нехватки памяти:

ThisWorkbook.Sheets("Name").Cells.Value = Target_Sheet.Cells.Value

Почему это происходит?Предполагается, что метод более эффективен.

В качестве альтернативы я хочу использовать метод копирования и обойти буфер обмена, используя что-то вроде следующего кода.Но как я могу указать, что мне нужны только значения?

Sheet1.Range("A1:A200").Copy Destination:=Sheet2.Range("B1")

1 Ответ

0 голосов
/ 26 ноября 2018

Итак, в вашем сообщении есть несколько вопросов:

1. Почему это происходит?

Поскольку вы обрабатываете весь набор ячеек.Это слишком велико, поэтому возникает ошибка «недостаточно памяти».ошибочный бит в вашем коде - это часть: .Cells.Value.Чтобы предотвратить нацеливание на все ячейки, необходимо указать диапазон, как описано ниже.

2. Как использовать копирование / вставку только со значениями

На самом деле единственный способэто сделать так, как вы изначально написали (кроме части .Cells) в своем «менее эффективном методе».Сначала вы копируете диапазон, затем он сохраняется в буфере обмена, затем вы выбираете пункт назначения и, наконец, используете функцию «вставить».Вы можете увидеть этот другой вопрос для дополнительных подробностей о "paste" против "paste special" .Так что если вы замените .Cells на .UsedRange, вы уже увидите улучшение скорости.

3. Как сделать более эффективную копию

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

Target_Sheet.Copy Before:=ThisWorkbook.Sheets("Name")

Если это не соответствует вашим потребностям, вы должны соответствовать разным размерам исходного диапазона идиапазона назначения.Как уже упоминалось в комментариях, это можно сделать с помощью UsedRange.

dim rowOrigin as long
dim colOrigin as long
dim rowEnd as long
dim colEnd as long
Dim Origin_Sheet As Worksheet: Set Origin_Sheet = Sheets("Sheet1")
Dim Destination_Sheet As Worksheet: Set Destination_Sheet = Sheets("Sheet2")

colEnd = Origin_Sheet.UsedRange.Columns.Count
rowEnd = Origin_Sheet.UsedRange.Rows.Count
colOrigin = Origin_Sheet.UsedRange.Column
rowOrigin = Origin_Sheet.UsedRange.Row

Destination_Sheet.Range(Destination_Sheet.Cells(rowOrigin, colOrigin), Destination_Sheet.Cells(rowEnd, colEnd)).Value = _
    Origin_Sheet.Range(Origin_Sheet.Cells(rowOrigin, colOrigin), Origin_Sheet.Cells(rowEnd, colEnd)).Value
...