powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Копирование данных из одногоф айла Excel в другой
19 сообщений из 19, страница 1 из 1
Копирование данных из одногоф айла Excel в другой
    #35738179
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток

Поставлена следующая задача: сделать так, чтобы все изменения автоматом фиксировались в другом файле XLS. Причины постановки неизвестны, идея, видимо, в том, что етсь некое центральное хранилище данных, в которое автоматом копируется информация из заполняемых накладных.

Решение состоит в создании нового объекта Application и открытии в нем файла-приемника. Далее в обработчике события OnSheetChange изменения и копируются.

Выглядит все вот таким образом:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
'эта переменная указывает на второе приложение Excel, в котором открыт файл-приемник данных
Private TargetApp As Application

Private Sub Workbook_Open()
    
    Set TargetApp = Nothing
    
On Error GoTo ErrorHandler
    
    'определимся с полным именем файла, в который будем писать
    Dim destFullName As String
    destFullName = ActiveWorkbook.path + "\destination.xls"
    
    'создаем еще один объект-приложение Excel и в нем открываем файл-приемник
    Set TargetApp = New Application
    TargetApp.Visible = False
    TargetApp.Workbooks.Open (destFullName)
    
    Exit Sub
    
ErrorHandler:
    s = "Проблема с файлом-приемником данных ('. " + fullName
    s = s + "'). Код: " + Str(Err.Number)
    s = s + ", описание: "
    s = s + Err.Description
    MsgBox s, vbCritical, "ЕГГОГ"
    
    Set TargetApp = Nothing
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    If TargetApp = Empty Or TargetApp Is Nothing Then
        Exit Sub
    End If
    
    'сохраняем изменения в приемнике
    TargetApp.Workbooks( 1 ).Save
    'закрываем приложение-приемник
    TargetApp.Quit
    
    'Внимание. Если открыто два источника, связанные с одним и тем же приемником, то будут косяки
    'как оно решается, я не в курсе. Текущая версия работает только в однопользовательском режиме
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal r As Range)
    If TargetApp = Empty Or TargetApp Is Nothing Then
        Exit Sub
    End If
    
    'приемник данных - приложение TargetApp.Workbooks(1).Sheets(1)
    'в цикле установим новые значения ячеек приемника
    'вообще-то, наверняка можно скопировать данные из [Range r] одним махом
    'но хз как. А используемый метод медленный
    For cellNum =  1  To r.Cells.Count
        Col = r.Cells(cellNum).Column
        Row = r.Cells(cellNum).Row
        TargetApp.Workbooks( 1 ).Sheets( 1 ).Cells(Row, Col) = r.Cells(cellNum)
    Next cellNum
    
End Sub

Два вопроса:
1. Каким образом можно скопировать Range измененых ячеек из источника в приемник одним махом, а не перебирая ячейки в цикле?
2. При закрытии файла-источника приемник закрывается автоматом. Если одновременно два источника связаны с одним приемником, возникают проблемы. Я так подозреваю, что Application, как СОМ-объект, должен предоставлять доступ к методу Release (или как его), который уменьшает счетчик ссылок. Метода такого, к сожалению, не нашел. Если же писать просто "Set TargetApp = Nothing", то приложение-приемник из памяти не выгружается. Второй вариант - можно ли как-то узнать, сколько ссылок имеется на данный момент у Application приемника? В этом случае приложение-источник при закрытии могло бы выяснять, связан ли приемник еще с кем-то, кроме данного источника и при отсутствии связей закрывать приемник.
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35738247
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1.
Код: plaintext
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal r As Range)\n    If TargetApp = Empty Or TargetApp Is Nothing Then Exit Sub\n    r.Copy TargetApp.Workbooks( 1 ).Sheets( 1 ).Range(r.Cells( 1 ,  1 ).Address)\n    \'приемник данных - приложение TargetApp.Workbooks(1).Sheets(1)\n    \'в цикле установим новые значения ячеек приемника\n    \'вообще-то, наверняка можно скопировать данные из [Range r] одним махом\n    \'но хз как. А используемый метод медленный\n\'    For cellNum = 1 To r.Cells.Count\n\'        Col = r.Cells(cellNum).Column\n\'        Row = r.Cells(cellNum).Row\n\'        TargetApp.Workbooks(1).Sheets(1).Cells(Row, Col) = r.Cells(cellNum)\n\'    Next cellNum\n\nEnd Sub\n
2.
В двух экземплярах Excel-я, невозможно открыть один и тот же файл на редактирование, во втором экземпляре можно открыть в режиме "только чтение", если только у файла не выставлен режим "общий доступ", это "сервис->доступ к книге->разрешить совместный доступ. При таком режиме есть ограничения: VBA и общий доступ
Перед тем как писать "Set TargetApp = Nothing", нужно закрыть все открытые в нем книги. Примерно так
Код: plaintext
TargetApp.Workbooks("destination.xls").Close True \'or false
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35739732
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
непонятно "все изменения автоматом фиксировались в другом файле XLS".

все равно же они потом затираются? в чем отличие от просто сохранения копии перед закрытием?
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35740659
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за помощь, :-)

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

А изменения вполне даже успешно сохраняются, почему бы и нет?
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35740678
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще вот такой вопрос по копированию диапазонов ячеек:
в предлагаемой Вами строке "r.Copy TargetApp.Workbooks(1).Sheets(1).Range(r.Cells(1, 1).Address)" я беру вот это: "r.Cells(1, 1).Address" и мой Excel сообщает о том, что нет такого свойства Adress. У меня 2007 версия. А можно каким-то другим методом вообще получить строковое название столбца, в котором расположена ячейка?
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35741053
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JohnSparrowЕще вот такой вопрос по копированию диапазонов ячеек:
в предлагаемой Вами строке "r.Copy TargetApp.Workbooks(1).Sheets(1).Range(r.Cells(1, 1).Address)" я беру вот это: "r.Cells(1, 1).Address" и мой Excel сообщает о том, что нет такого свойства Adress. У меня 2007 версия. А можно каким-то другим методом вообще получить строковое название столбца, в котором расположена ячейка?

Adress - действительно нет, а вот Address - есть.
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35741139
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkodor,
пишите просто r.address

или, если уж очень хочется, r.cells(1).address
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35741142
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_slan_,
а точнее r.address(0,0) в вашем случае
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35741500
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_slan_, это не просто моё желание, в этом есть смысл.
Строчка - "r.cells(1).address" подойдет, а вот строчка - "r.address" в определенный момент даст сбой.

P.S. Иногда стоит проверить информацию, прежде чем писать. Этому меня научил этот форум.
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35741516
vkodor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_slan__slan_,
а точнее r.address(0,0) в вашем случае
А это в данной ситуации, уж совсем лишнее. Только лишние символы кода и все.
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35742141
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkodor, в каком случае это не проходит?

со вторым согласен.
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35742158
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если я копирую данные из одного листа в другой в рамках текущей рабочей книги, то все выходит:
Код: plaintext
Workbooks( 1 ).Sheets( 1 ).Range("A1:D4").Copy Worksheets( 1 ).Range("A1")
Если же (как в моем случае - см. пост №1) обе книги открыты в разных приложениях и код вот такой:
Код: plaintext
Workbooks( 1 ).Sheets( 1 ).Range("A1:D4").Copy TargetApp.Worksheets( 1 ).Range("A1")
То появляется сообщение об ошибке с кодом 1004 и описанием "Метод Сору класса Range завершен неверно". Видимо, копирование через Range.Copy между двумя процессами Excel не проходит. Тогда вопрос такой: а могу я вторую рабочую книгу (приемник данных) открыть в текущем процессе Excel, однако при этом сделать ее невидимой?
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35742182
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JohnSparrow, такой код работает(проверено на 2007м)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Sub Макрос3()
Dim tapp As New Excel.Application
    tapp.Workbooks.Add
     [a1].Copy
   tapp.ActiveSheet.Paste
   Application.CutCopyMode = False
    tapp.Visible = True
End Sub
если не надо копировать все(достаточно только значений) , то можно просто писать:
tapp.[a1]=[a1]
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35742192
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну и
Код: plaintext
1.
    Workbooks.Add
    ActiveWindow.Visible = False
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35742209
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за подсказку, однако, боюсь, нужно несколько иное. Суть вопроса в том, что на основании значений, введенных в определенные ячейки файла-источнике, нужно выполнить некоторые действия в файле-приемнике. Причины постановки такой странной задачи мне не пояснили, а сам постановщик вообще никогда с VBA дела не имел.

Я остановился на автоматическом выполнении этих магических действий в обработчике Workbook_SheetChange исходного файла. Т.е. при каждом изменении ячейки скрипт проверяет, нужна ли нам эта ячейка и, если да, то, используя введенное в нее значение, скрипт делает что-то с одной или несколькими ячейками приемника. Простое копирование ячейки в приемник после ее изменения в источнике я взялся делать оттого, чтобы вообще научиться организовывать взаимодействие между двумя книгами (VBA не занимаюсь, потребность возникает эпизодически). Оно как бы и получилось за исключением проблемы, связанной с Range.Copy между разными процессами.

Ну а это самое взаимодействие в данном случае для пользователя должно быть невидимым. Т.е. пользователь должен видеть только одну рабочую книгу - источник, а что там, где и каким образом происходит - его не касается. Отсюда требование к приемнику быть невидимым. Чтобы книга-приемник была невидимой, ее надо открывать в отдельном приложении Excel, у которого есть свойство Visible и это свойство не выбрасывает исключение при попытке доступа к нему (как, например, Workbooks.Sheets.Visible , если открыть источник и приемник как две книги в рамках одно Application.Excel). А открыв приемник в отдельном приложении, получим проблему копирования, описанную во втором абзаце.
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35742224
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за подсказку насчет ActiveWindow.Visible = False. переделал так, чтобы и приемник и источник открывались в рамках одного Application.Excel. Ниже приведен код обработчиков событий Workbook приемника. Теперь все, кажется, работает, только после закрытия источника остается пустое окно, всех благ ему в новом году, :-). Еще раз большое спасибо за помощь, в общем и целом проблема решена, как я понимаю.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
Private Sub Workbook_Open()
On Error GoTo ErrorHandler
    
    'определимся с полным именем файла, в который будем писать
    Dim destFullName As String
    destFullName = ActiveWorkbook.path + "\destination.xls"
    
    'открываем приемник в качестве еще одной Workbook
    Workbooks.Open (destFullName)
    'и делаем его невидимым
    ActiveWindow.Visible = False
    
    'активируем и делаем видимым источник
    Workbooks( 1 ).Activate
    ActiveWindow.Visible = True
    
    Exit Sub
    
ErrorHandler:
    s = "Код: " + Str(Err.Number)
    s = s + ", описание: "
    s = s + Err.Description
    MsgBox s, vbCritical, "ЕГГОГ"
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    If Workbooks.Count >  1  Then
        'активируем и делаем видимым приемник
        Workbooks( 2 ).Activate
        ActiveWindow.Visible = True
        
        'сохраняем изменения в приемнике
        Workbooks( 2 ).Save
        'закрываем приемник
        Workbooks( 2 ).Close
    End If
       
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal r As Range)
    If Workbooks.Count >  1  Then
        r.Copy Workbooks( 2 ).Worksheets( 1 ).Range(r.Cells( 1 ,  1 ).Address)
    End If
End Sub
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35742436
ART-CODE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я не совсем понимаю - почему Вы не пользуетесь таким удобным механизмом как
работа с xls через ADO , выполняя SQL запросы Select, Insert, Update
вот например что-то вроде этого....
это фрагмент vbs скрипта, работающего внутри HTA странички
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
Dim fso
Dim WorkDir
WorkDir="C:\Temp"
Set fso = CreateObject("Scripting.FileSystemObject")
'-------------------------------------------------------------------------
 sub TestSelect()
    Const adOpen =  3   
    Dim row_num
    Dim cnn
    Dim rst
    Dim msg_str    

    Set cnn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")

    cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
      "Data Source=C:\Temp\test.xls;" & _
      "Extended Properties=""Excel 8.0;HDR=No;IMEX=2"""
    
    rst.Open "SELECT * FROM [Sheet1$]", cnn, adOpen
    
    row_num= 1 
    Do Until rst.EOF    
    for i =  0  to rst.fields.count -  1            
            log(rst.Fields(i).Name& "R:"&CStr(row_num)&" F:" & CStr(i+ 1 ) & "  "& rst.Fields(i).Value & vbcrlf)
        next
    row_num=row_num+ 1         
        rst.MoveNext
    Loop
MsgBox "test - end."
end sub
'-------------------------------------------------------------------------
Sub log(sData)  ' запись логов
    Dim ts, ForAppending
    ForAppending =  8 
    Set ts = fso.OpenTextFile(WorkDir&"\xls.log", ForAppending, True)
    ts.Write Date & " - "& Time() & " " & sData & chr( 13 ) & chr( 10 )
    ts.Close
End Sub


и еще - я-бы заменил приемник на нормальный SQL сервер с хранимками и триггерами, а уже оттуда выливал все что надо и куда надо...
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35742847
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я уже писал - вообще работа с файлом XLS, который параллельно взаимодействует с другим файлом XLS (типа, централизованное хранилище данных) мне самому кажется странной, зачем оно им нужно, мой знакомый толком пояснить не смог. Скорее всего, его просто попросили сделать те, кто не в курсе о существовании СУБД, а для чего - не сказали.

Насчет работы с данными через ADO. Судя по всему, простое копирование по одной ячейке из источника и вставка в приемник вряд ли будет медленнее. Зато кода уж точно будет больше, :-).

ART-CODE и еще - я-бы заменил приемник на нормальный SQL сервер с хранимками и триггерами, а уже оттуда выливал все что надо и куда надо...
Согласен. Создание велосипеда с шестью колесами, когда уже есть двухколесный, - не самая лучшая идея.

С Новым годом, :-).
...
Рейтинг: 0 / 0
Копирование данных из одногоф айла Excel в другой
    #35793203
kislicin1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Подскажите плиз у меня вот такая проблемма.
Есть таблица готовая 1, забиты все формулы и тд. Есть ещё одна таблица 2 (я её выгружаю из SAP) мне нужно чтобы данныу из таблицы 2 ыгружались в таблицу 1. Притом в обоих таблицах есть столбец "Материал" дак вот мне надо чтоб данные переносились из строки с материалом Н в строку с этимже материалом в другой таблице.
Как это сделать?
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Копирование данных из одногоф айла Excel в другой
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]