Страницы: 1
RSS
Макрос на одном ПК работает корректно, на другом возвращает значения в книгу источник
 

Всем добрый день!

Есть легкое непонимание, т.к. на одном пк макрос работает корректно и переносит значения ячеек из таблицы "Таблицаисточник" в "Таблицаприемник".

При попытке скопипастить макрос с заменой путей на актуальный, выходит ошибка 9, т.к. макрос не видит листа "Лист1" в "Таблицаисточник", но если добавить лист под названием "Лист1" - все значения исправно встают куда им нужно, но не в ту книгу.

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

Не мог бы кто-нибудь дать комментарий?)

Код
Sub КопироватьЯчейки()
    ' Указываем имена файлов и диапазоны ячеек для копирования
    Const файлWorkbook1 As String = "C:\Users\Timon\Desktop\Таблицаисточник.xlsx"
    Const файлWorkbook2 As String = "C:\Users\Timon\Desktop\Таблицаприемник.xlsm"
    Const диапазонDiap1 As String = "A2:O2"
    Const диапазонDiap2 As String = "P2:AD2"

    ' Открываем файлы
    Dim wbИсточник As Workbook, wbПриемник As Workbook
    Set wbИсточник = Workbooks.Open(файлWorkbook1)
    Set wbПриемник = Workbooks.Open(файлWorkbook2)

    ' Выбираем активные листы в обоих книгах
    Dim wsИсточник As Worksheet, wsПриемник As Worksheet
    Set wsИсточник = wbИсточник.Sheets("Sheet1")
    Set wsПриемник = wbПриемник.Sheets("Лист1")

    ' Находим последнюю заполненную строку в столбце A на листе источника
    Dim последняяСтрока As Long
    последняяСтрока = wsИсточник.Cells(wsИсточник.Rows.Count, "A").End(xlUp).Row

    ' Копируем данные из диапазона источника в диапазон приемника
    wsИсточник.Range(диапазонDiap1 & ":A" & последняяСтрока).Copy _
        Destination:=wsПриемник.Range(диапазонDiap2 & ":P" & последняяСтрока)


End Sub

 
я может чего не понимаю...Но как это может вообще корректно работать?
Цитата
Артём Б написал:
Const диапазонDiap1 As String = "A2:O2"
Const диапазонDiap2 As String = "P2:AD2"
Цитата
Артём Б написал:
wsИсточник.Range(диапазонDiap1 & ":A" & последняяСтрока).Copy _
       Destination:=wsПриемник.Range(диапазонDiap2 & ":P" & последняяСтрока)
Если предположить, что последняя строка у нас будет равна 45, получится вот это:
Код
wsИсточник.Range("A2:O2:A45").Copy _
        Destination:=wsПриемник.Range("P2:AD2:P45")

На Ваш взгляд, похоже это на рабочую конструкцию? Нет, не так. Она работать будет, без сомнения. Но похоже это на что-то понятное? На мой взгляд нет.
Может константы правильнее было объявить все же без второй ячейки? Или хотя бы без последней строки - тогда надо было бы подставить только её:
Код
Const диапазонDiap1 As String = "A2:O"
Const диапазонDiap2 As String = "P2:AD"
...
wsИсточник.Range(диапазонDiap1 & последняяСтрока).Copy _
        Destination:=wsПриемник.Range(диапазонDiap2 & последняяСтрока)


Ну а в остальном не вижу каких-либо проблем, чтобы код не работал. Попробуйте привести в порядок и проверить работу. И да - при вставке в аргументе Destination можно указать вообще только начальную ячейку - начиная с неё вставлены будут все скопированные:
Код
Const диапазонDiap1 As String = "A2:O"
Const диапазонDiap2 As String = "P2"
...
wsИсточник.Range(диапазонDiap1 & последняяСтрока).Copy _
        Destination:=wsПриемник.Range(диапазонDiap2)

Цитата
Артём Б написал:
если добавить лист под названием "Лист1" - все значения исправно встают куда им нужно, но не в ту книгу.
вот это, кстати, вообще непонятно. Даже представить не могу, в каком сценарии при приведенном коде это может произойти. Может, Вы нам чего-то не показали?
С одной стороны как бы очевидно - значит в книге просто нет листа "Лист1"(может там пробел лишний какой). А с другой - почему тогда переносит данные в другую книгу? Другую - это какую и откуда она берется? А если открыть только две нужных книги и скопировать имя листа прямо из кода - что будет?
В общем, мне кажется, что просто лист называется не "Лист1".
Изменено: Дмитрий(The_Prist) Щербаков - 21.03.2023 17:45:05
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
Дмитрий(The_Prist) Щербаков: как это может вообще корректно работать?
полностью согласен — потому и писать ничего не стал, т.к. "рабочий" код может быть совсем другим на самом деле  :)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Дмитрий(The_Prist) Щербаков, К сожалению, всё не так просто, а я пользуюсь всевозможными источниками (включая чатжпт) при построении макросов и возможно не всегда понимаю как должно быть, давайте попробую сформулировать:

Ограничение второй ячейкой О2 сделано специально, чтобы не затягивались данные из столбцов идущих в "Таблицаисточник" дальше.

Также ограничить строки не представляется возможным, т.к. ограничение я устанавливал до первой незаполненной ячейки в столбце "А" источника, т.к. количество строк постоянно дополняется.

Я не могу определить почему ячейки копируются не в "Приёмник", а в "Источник", хотя на другом пк все работает корректно.
Цитата
С одной стороны как бы очевидно - значит в книге просто нет листа "Лист1"(может там пробел лишний какой). А с другой - почему тогда переносит данные в другую книгу? Другую - это какую и откуда она берется? А если открыть только две нужных книги и скопировать имя листа прямо из кода - что будет?
Собственно как это работает на ноутбуке
Есть две книги, источник и приемник.
При выполнении макроса на другом пк, заполненные ячейки таблицы "Источник" листа "Sheet1" с "А2" до "О2" копируются в таблицу "Приемник" на лист "Лист1" в ячейки с "P2" до "AD2", и так до последней строки где заполнена ячейка "А" таблицы "Источник".
При переносе макроса на мой пк путем копипасты и замены путей на актуальные, получаем, что до шага с открытием книги "Приемник" код выполняется, а дальше, все действия происходят только внутри таблицы "Источник", и получается что если оставить в "Источнике" только лист "Sheet1" - выкидывается ошибка 9, на шаге
Код
 Set wsПриемник = wbПриемник.Sheets("Лист1")

НО

Если добавить в таблицу "Источник" пустой лист, который создается с названием "Лист1" - ячейки превосходно в него копируются, при этом таблица "Приемник" висит открытой без изменений.

Цитата
написал:
В общем, мне кажется, что просто лист называется не "Лист1".
Названия листов менять пробовал, как и пути к файлу, оставляя кириллицу, убирая - нет разницы.

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

Я может не совсем корректно формулирую, но постарался расписать шаг за шагом)

Изменено: Артём Б - 21.03.2023 18:05:05
 
Да даже по описанию - я бы поверил, если бы не это:
Код
Set wsПриемник = wbПриемник.Sheets("Лист1")

здесь четко прописано, что "Лист1" надо брать из книги приемника. И копироваться в Источник может только в одном случае - если книга Приемник и книга Источник - это одна и та же книга.
Цитата
Артём Б написал:
Ограничение второй ячейкой О2 сделано специально, чтобы не затягивались данные из столбцов идущих в "Таблицаисточник" дальше
на бред похоже. Так копируйте то кол-во столбцов, которое нужно, в чем проблема-то? Так же и строки - что скопируете, то и перенесете.
Это во-первых. А во-вторых: ограничением это не называется. Я же показал, что получается. Вам надо не ChatGP штудировать, а азы по VBA. Тогда хоть какое-то понимание было бы, что я Вам написал и почему Ваш код выглядит несуразно, хоть и работает. Плюс ничего это не ограничивает - сколько скопируете, столько и вставите. Вот для примера простейший код копирования-вставки на одном листе:
Код
Range("A1:D5").Copy Destination:=Range("G1:H4")

это тот же Ваш код, просто я делаю все внутри активного листа. Обратите внимание - копирую я 5 строк и 4 столбца. В качестве диапазона назначения ограничил двумя столбцами и 4-мя строками. Но если выполнить код - то начиная с G1 вставлены буду все скопированные 5 строк и 4 столбца. Все потому, что аргумент Destination принимает только одну верхнюю левую ячейку указанного диапазона и с неё начинает вставку всех скопированных ячеек.
Так что как уже говорил - Ваши старания по указанию диапазона в книге-приемнике весьма избыточны.

В общем проблема явно где-то еще. Нет никаких посылов для того, чтобы скопированное вставлялось не в ту книгу, которая явно указана. Где-то Вы нам, скорее всего, чего-то не договариваете.
Изменено: Дмитрий(The_Prist) Щербаков - 21.03.2023 18:17:49
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Дмитрий(The_Prist) Щербаков,  я даже не знаю что ответить.

Сейчас попробовал всё с нуля, оставил код как есть, назвал листы цифрами - результат тот же.

Если в источнике нет листа с названием "2" вылезает ошибка.
Если есть - копируется туда, при этом приемник чист.
Может быть есть разница что источник в формате .xslx, приемник .xlsm, хотя на ноуте с теми же вводными все работает.
Если есть пара свободных минут, гляньте пожалуйста файлы.

Приложу оба, может я несознательно что-то недоговариваю?)

А с азами vba это вы правы, надо, но как всегда со временем беда, пользуемся ускоренными решениями, просто файл на 5000 строк и постоянно пополняющийся на формулах очень сложно работает)
 
А вот скажите...
Вы код-то откуда запускаете? Не из файла "Приемник", случаем? Если да - зачем Вы его открываете? Он же открыт уже.
Ну и сразу скажу - у меня все отработало без проблем и правок. Но именно вот переоткрытие файла с кодом может давать сбой в кодах.
Попробуйте записать код так(если код запускаете именно из файла "Приемник", конечно):
Код
Sub КопироватьЯчейки()
    ' Указываем имена файлов и диапазоны ячеек для копирования
    Const файлИсточник As String = "C:\Users\Timon\Desktop\Источник.xlsx"
'    Const файлПриемник As String = "C:\Users\Timon\Desktop\Приемник.xlsm"
    Const диапазонДиапазон_копирования As String = "A2:O2"
    Const диапазонДиапазон_вставки As String = "P2:AD2"

    ' Открываем файлы
    Dim wbИсточник As Workbook, wbПриемник As Workbook
    Set wbИсточник = Workbooks.Open(файлИсточник)
    Set wbПриемник = ThisWorkbook 'Workbooks.Open(файлПриемник)

    ' Выбираем активные листы в обоих книгах
    Dim wsИсточник As Worksheet, wsПриемник As Worksheet
    Set wsИсточник = wbИсточник.Sheets("1")
    Set wsПриемник = wbПриемник.Sheets("2")

    ' Находим последнюю заполненную строку в столбце A на листе источника
    Dim последняяСтрока As Long
    последняяСтрока = wsИсточник.Cells(wsИсточник.Rows.Count, "A").End(xlUp).Row

    ' Копируем данные из диапазона источника в диапазон приемника
    wsИсточник.Range(диапазонДиапазон_копирования & ":A" & последняяСтрока).Copy _
        Destination:=wsПриемник.Range(диапазонДиапазон_вставки & ":P" & последняяСтрока)


End Sub
Изменено: Дмитрий(The_Prist) Щербаков - 21.03.2023 18:54:43
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Дмитрий(The_Prist) Щербаков, заработало

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

И да, заработало, вероятно эта строка кода всё меняет.
Код
Set wbПриемник = ThisWorkbook 'Workbooks.Open(файлПриемник)

Спасибо большое, буду читать про свойства в общем и ThisWorkbook в частности. Думал то в правильную сторону, в сторону AсtiveWorkbook но думалка не вывезла)

Еще раз благодарю за помощь и то что повозились в песочнице)
 
Цитата
Артём Б: я пользуюсь всевозможными источниками (включая чатжпт)
ахахахах
    Никогда такого не было [с "убийцей программистов"] и вот опять :D
Изменено: Jack Famous - 22.03.2023 09:50:28
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх