#excel #vba
#excel #vba
Вопрос:
Итак, цель этого макроса — открыть определенный файл, чтобы затем скопировать из этого файла и вставить обратно в исходную книгу, где хранится макрос.
Стоит отметить элементы, которые делают этот макрос немного уникальным:
Workbook A (wbDestination) — Excel с несколькими листами, где будет сохранен макрос и куда будет вставлена информация из Workbook B. Расположение пути к файлу для книги B будет меняться ежемесячно, поэтому я создал функцию в этой книге A, где макрос сможет успешно находить путь к файлу, чтобы соответствовать ежемесячному изменению местоположения пути к файлу. Мне нужно, чтобы исходные данные из книги B были вставлены в «Лист2» в книге A. Расположение пути к файлу книги B находится в ячейке C2 на листе под названием «Макросы» в книге A.
Workbook B (wbSourceData) — Excel с несколькими листами, где будут храниться исходные данные, которые мне нужно скопировать и вставить в Workbook A. Исходные данные, которые я буду копировать, находятся на втором листе.
Sub CopyPaste()
Dim wbSourceData As Workbook
Dim wbDestination As Workbook
Dim wsSourceData As Worksheet
Dim wsDestination As Worksheet
Dim strFName As String
Set wbDestination = ThisWorkbook
Set wsDestination = wbDestination.Sheets("Sheet2")
strFName = wbDestination.Worksheets("Macros").Range("C2").Value
Set wbSourceData = Workbooks.Open(strFName)
Set wsSourceData = wbSourceData.Worksheets(2)
wsSourceData.Range("A2").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
wsDestination.Select
Range("A4").Select
Selection.PasteSpecial Paste:=xlPasteValues
wbSourceData.Close SaveChanges:=False
End Sub
Некоторые другие вещи, на которые следует обратить внимание. Я успешно могу открыть книгу B в этой функции, но затем макрос умирает, когда я пытаюсь скопировать данные. Ошибка, которую я получаю в «Ошибка времени выполнения ‘1004’: ошибка выбора метода класса диапазона». Я также хочу использовать функции выбора диапазона xlToRight (дважды) и xlDown в рабочей книге A, потому что количество строк этих исходных данных будет меняться ежемесячно, и это лучший способ захватить весь диапазон. Мне понадобятся исходные данные из книги B, которые будут вставлены обратно в книгу A в качестве значений вставки.
Я новичок в VBA, поэтому все, что необходимо для исправления этого макроса, пожалуйста, ELI5, спасибо! Я действительно ценю это!
Ответ №1:
Очень красиво настроен. Мне нравится, с какой тщательностью вы подошли к названию. Это очень полезно. Но когда дело дошло до копирования / вставки, вы не читали главу, где говорилось «вам не нужно ничего выбирать». Вот улучшенная версия этой части кода.
With wsSourceData
' last used cell in row 2 looking from right to left
Cl = .Cells(2, .Columns.Count).End(xlToLeft).Column
' last used row in column A looking from bottom up
Rl = .Cells(.Rows.Count, "A").End(xlUp).Row
Set Rng = .Range(.Cells(2, "A"), .Cells(Rl, Cl))
End With
Rng.Copy Destination:=wsDestination.Range("A4")
Как вы видите, задача состоит в том, чтобы указать Range
. Конечно, Selection
объект — это диапазон. Excel использует его для передачи в свой бэк-офис того, что пользователь нажал на экране. Он не очень хорошо подходит для чего-либо еще и поэтому используется вместо диапазона всякий раз, когда используется. Следовательно, идите прямо к диапазону, если это тот диапазон, который вам нужен.
xlToRight
ищет следующую пустую ячейку справа. xlToLeft
ищет первую использованную ячейку справа. Ваш код перепрыгивает через пустую ячейку, чтобы найти конец. То же самое для просмотра сверху вниз или с конца вверх. Я надеюсь, что справа больше нет заполненных ячеек, которые вы, на самом деле, хотите исключить, или сверху вниз. Если это так, переменные Rl
и Cl
должны быть найдены с использованием используемого вами кода. Настройка диапазона будет выполняться с теми же переменными, установленными по-другому.
Вот объявления, которые я добавил к тем, которые у вас уже есть.
Dim Rng As Range
Dim Cl As Long ' last used column
Dim Rl As Long ' last used row
Комментарии:
1. Спасибо за ответ, я это очень ценю!! Итак, я добавил эти три объявления под первыми пятью, которые я написал. Я полностью очистил, скопировав и вставив код, который я написал. Из строки wsSourceData.Range(«A2»). Выберите вниз, чтобы выбрать. Вставить специальную вставку:=xlPasteValues . Я заменил этот код написанным вами кодом. Я не получаю никаких ошибок, что хорошо, но я не получаю желаемых результатов, поскольку информация не вставляется в мое назначение wsDestination.
2. Я хотел бы уточнить, что я сразу скопировал и вставил ваш код. Из ваших заметок, я думаю, вы просите меня немного отредактировать код, который вы написали, чтобы указать мой диапазон. Я могу сказать вам, что диапазон, который я буду захватывать, всегда будет из столбцов A — N, поэтому столбцы 1-15. Однако количество строк будет меняться каждый месяц. Возможно, стоит отметить, что исходные данные имеют заголовки столбцов, которые я НЕ хочу копировать, поэтому я хочу, чтобы макрос копировал, начиная со второй строки.
3. При просмотре я обнаружил, что диапазон назначения должен быть указан правильно, и я изменил эту строку в своем ответе на чтение
Rng.Copy Destination:=wsDestination.Range("A4")
. Похоже, вы не проанализировали точную ошибку, которую вы получаете. Если выбор места назначения был проблемой, вышеуказанное должно устранить ее. Если это выбор диапазона источника, добавьтеDebug.Print Rng.Address
нижеSet Rng =
и посмотрите, что с ним не так. Наличие подсказки облегчит обнаружение и исправление ошибки.4. Это был пункт назначения, который был ошибкой. Это исправлено!! Я не могу передать вам, как я вам благодарен!
5. Эй, я знаю, что это было некоторое время назад, но есть ли какой-нибудь способ, которым вы могли бы знать, как вставить в качестве значений. Я сталкиваюсь с небольшой проблемой, потому что, когда исходные данные вставляются в пункт назначения, макрос переносит формат из исходных данных. Затем я должен переделать формат в пункте назначения до того, каким он был ранее. Итак, я думал как-то немного изменить макрос, чтобы исходные данные вставлялись в качестве значений в пункт назначения? Спасибо