Страницы: 1
RSS
Макрос записи в Word перестал работать
 
Уважаемые господа, помогите ответить на такой теоретический вопрос.
Есть макрос. Вот его начало (поскольку ошибка здесь дальнейший текст не привожу):
Код
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Sub main()
    On Error Resume Next
    Dim wa As Object
    Dim wd1 As Object
    Dim wd2 As Object
    Dim wd3 As Object
    Dim aText(51) As String                
 
    tm_num% = 51
    row_one% = 62
 
    For i = 0 To tm_num%
        aText(i) = Range("H" & i + row_one%).Text
    Next i
...
Там дальше в цикле элементы массива записываются в Word-файл. Все работало. Но один раз что-то случилось с docx-файлом (он был открыт, а в него пошла запись из макроса или другая какая ошибка, думаю не имеет значения) и после этого макрос работать перестал. Word-документ создавался, но с пустыми строками. Я стал разбираться и оказалось, что массив aText пустой. Предыдущий вариант макроса работал. Целый день я искал в чем ошибка в этом кусочке - не нашел и просто перенабрал текст цикла... и все заработало. Для меня это мистика. Может кто-нибудь это объяснить.
 
Похоже по тому, что нет конкретного указания из какого листа (и, возможно, какой книги) брать, а активен не тот лист (или книга) откуда надо брать значения.
А такая запись берёт из активного листа активной книги
 
ув. Александр,
спасибо за ответ. Но кнопка вызова макроса находится на том же листе откуда берутся данные. Нажимая на кнопку я делаю активным и лист. Или я заблуждаюсь?
 
А что это за строки?
tm_num% = 51
row_one% = 62
 
Я спрошу по ходу:
Зачем нужен знак %
Код
1
2
tm_num% = 51
row_one% = 62
Код работает безошибочно.
Возможно, что при создании doc он у вас оставался активным, что само по себе правильно, а файл Excel был на заднем фоне. И при обращении к ячейке или куда либо в другое место Excel, он попадал на Doc, тем самым выдавал ошибку. Поэтому файл был создан но данные не перенеслись. И лучше использовать пути при создании других файлов, так как винда по разному может среагировать на созданный файл. Может поместить его на перед, или запустить в свёрнутом состоянии и деактивировать все окна.
Изменено: CAHO - 16.11.2015 20:10:54
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.
 
Цитата
vadi61 написал:
Нажимая на кнопку я делаю активным и лист. Или я заблуждаюсь?
заблуждаетесь, ноне сильно. Если кнопка на листе, то нажать на не можно, только если лист активный.
...Ветер не от того, что деревья качаются...
 
Ошибка может быть в том, что код записан в модуле листа. И хоть Вы и делаете потом активным нужный лист - данные берутся с листа, в модуле которого код. Подробнее об этом я здесь рассказывал: Как обратиться к диапазону из VBA
Поместите код в стандартный модуль.
Пока других причин нерабочего кода не видно.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Михаил С.,
tm_num% = 51
- это верхний предел цикла. У меня 52 ячейки со значениями, 52 элемента в массиве и 52 закладки в docx-документе куда вставляются эти значения.
row_one% = 62
- это номер строки верхней ячейки (колонки) диапазона ячеек со значениями (этих ячеек 52)

CAHO,
в этом файле Excel, на этой странице указаны имена dоcx-файлов. Если макрос верно берет имена файлов, то и остальные значения он должен брать правильно

На всякий случай привожу весь макрос:
Код
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
Sub main()
    On Error Resume Next
    Dim wa As Object
    Dim wd1 As Object
    Dim wd2 As Object
    Dim wd3 As Object
    Dim aText(51) As String                
 
    tm_num% = 51                          
    row_one% = 62                          
 
    For i = 0 To tm_num%                    
        aText(i) = Range("H" & i + row_one%).Text
    Next i
     
    file1_name$ = Cells(2, 8 ).Value        
    bm2_name$ = Cells(28, 8 ).Value        
    file2_name$ = Cells(29, 8 ).Value        
    bm3_name$ = Cells(34, 8 ).Value          
    file3_name$ = Cells(35, 8 ).Value  
    bm_text$ = Cells(36, 8 ).Value          
    bm_num% = Cells(37, 8 ).Value            
 
    HomeDir$ = ThisWorkbook.Path
    Set wa = CreateObject("Word.Application")
     
    FileCopy HomeDir$ + "\Doc\" + file1_name$, HomeDir$ + "\Result1.docx"      
    FileCopy HomeDir$ + "\Doc\" + file2_name$, HomeDir$ + "\Doc\Result2.docx"  
    FileCopy HomeDir$ + "\Doc\" + file3_name$, HomeDir$ + "\Doc\Result3.docx"  
 
    Set wd1 = wa.Documents.Open(HomeDir$ + "\Result1.docx")                  
    For ii = 0 To tm_num%                                                      
        marker = "tm_" & ii + 1                                              
        wd1.Bookmarks.Item(marker).Range.Text = aText(ii)
    Next ii
 
    Set wd2 = wa.Documents.Open(HomeDir$ + "\Doc\Result2.docx")                
    wd2.Range.Copy                                                            
    wd1.Bookmarks.Item(bm2_name$).Range.Paste                                  
    wd2.Close False                                                                                          
 
    Set wd3 = wa.Documents.Open(HomeDir$ + "\Doc\Result3.docx")              
    For iii = 1 To bm_num%                                                  
        marker = "Textmarke_" & iii                                          
        wd3.Bookmarks.Item(marker).Range.Text = bm_text$
    Next iii
    wd3.Save                                    
 
    wd3.Range.Copy                              
    wd1.Bookmarks.Item(bm3_name$).Range.Paste  
    wd3.Close                                      
 
    wd1.Close True                            
 
    wa.Quit                                    
    Set wa = Nothing
    MsgBox "Document is created."
End Sub
 
The_Prist,
код написан в модуле Modul1 раздела Module
 
А теперь все вместе подумаете и предложите название темы.
 
vikttur,
Вы поняли в чем причина? Называть тему Мистика в VBA как-то не того.
У меня был первый (работающий) вариант макроса в файле 1.xlsm и не работающий в файле 2.xlsm (у них разное количество ячеек с данными и разная методика подсчета данных в самом файле. В остальном - все одинаково). Я ставнивал все построчно - разницы не нашел. При этом
   For i = 0 To tm_num%
        aText(i) = Range("H" & i + row_one%).Text
        MsgBox  aText(i)
   Next i

выдавал пустые окна
Изменено: vadi61 - 16.11.2015 21:12:16
 
Я повторил эксперимент.
Запустил макрос при открытом Result1.docx. Все, привет. Макрос не заканчивается. Убил в диспетчере задач зависший Word. Удалил файл Result1.docx и пересохранил оригинал шаблона, из которого этот Result1.docx получается. Запускаю макрос - он не выполняется - часики крутятся, задача Word висит - ничего не происходит. Так было и в прошлый раз. Сейчас перезапишу файлы шаблонов из резервных копий (как пришлось сделать и в прошлый раз) - макрос заработает, но снова выше приведенный цикл ничего не выдаст. Пока в него не внести изменения вручную. Как будто Excel запоминает, что было что-то не так и просто игнорирует цикл...

PS. Windows 10
Office 2013
Изменено: vadi61 - 16.11.2015 21:28:16
 
Цитата
vadi61 написал:
Называть тему Мистика в VBA как-то не того.
Но и Ваше название "не того" - разве догадается другой посетитель форума искать АНАЛОГИЧНУЮ проблему в теме с таким названием? А вот писать в эту тему свои сообщения всем, у кого какая-либо ошибка в макросе - в самый раз ))
 
Юрий М
да я понимаю, что название подкачало, но я не нашел ничего подходящего - весь на эмоциях.

Вот сейчас (после эксперимента) перезаписал все файлы шаблонов и  2.xlsm (на всякий случай) из сохраненных ранее копий - запускаю: часики Windows крутятся, задача Word висит в диспетчере задач.

А копирую это все на внешний винчестер - запускаю: все работает. Ну как это понять!
Изменено: vadi61 - 16.11.2015 21:40:12
 
Тему изменил.
По проблеме: без файла с неработающим кодом проблему не выявить.
Но можно попробовать - уберите On Error Resume Next из кода - тогда VBA наверняка укажет на ошибочную строку. Отсюда надо плясать. Эта строка в этом коде все равно не нужна - она только мешает выявить возможные ошибки.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
The_Prist,
убрал. Запустил. Картина та же, часы и Ворд в диспетчере задач. Снял задачу.
Debugger подсветил строку 37. Set wd2 = wa.Documents.Open(HomeDir$ + "\Doc\Result2.docx").

Файл я могу выложить, но без шаблонов он ничего не даст. А шаблоны выбираются по результатам расчета в самом файле. Их в общей сложности 35 Мб.
 
Цитата
vadi61 написал:
Debugger подсветил строку 37
Это логично, т.к. Вы убили процесс Word - программе теперь не к чему обращаться и явно возникла ошибка автоматизации.

После строки:
Код
1
Set wa = CreateObject("Word.Application")
запишите:
Код
1
wa.Visible = True
Скорее всего при копировании и вставке Word показывает некое модальное сообщение, которое надо подтвердить нажатием. И тогда Word просто повиснет и код не будет выполняться дальше, пока не нажмете кнопку в сообщении. И чтобы понять, как убрать сообщение - надо знать что это за сообщение.
Возможно, поможет строка:
Код
1
wa.DisplayAlerts = false
Её надо поставить после запуска Word. Но может и не помочь, поэтому все же сначала советую сделать Word видимым и посмотреть, что за сообщение.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
The_Prist,
вот. Я сделал три файла шаблона (теперь в форме ввода (где кнопка "создать ТЦП") можно менять значения только в двух желтых квадратиках (остальных файлов просто нет) выкинул все картинки - форматирование сбилось, короче там ерунда, но для тестирования макроса подойдет.
2.xlsm и Doc.rar надо положить в одну папку и rar распаковать - создастся папка Doc с тремя файлами.
Сейчас все работает. Но если запустить макрос, то рядом с 2.xlsm создастся файл Result1.docx. Если его открыть и снова запустить макрос - Word прийдется снимать в диспетчере задач. После этого макрос уже работать не будет.
Изменено: vadi61 - 16.11.2015 22:44:02
 
Вы попробовали сделать как я написал?
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
vadi61 написал:
Если его открыть и снова запустить макрос - Word прийдется снимать в диспетчере задач
Ну вот угадайте - почему? Потому что нельзя просто так взять и заменить файл, который открыт. Word скорее всего об этом и сообщает, выдавая ошибку.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
The_Prist написал:
Вы попробовали сделать как я написал?
Я сразу не заметил  :oops: . Попробовал - действительно было окно.
Здорово. Одну проблему Вы решили. Спасибо!

Но теперь (Ворд видимый) он перед закрытием спрашивает хочу ли я сохранить в буфере тот фрагмент которых в него вставлялся. И мне надо вручную нажать на ДА или НЕТ - только тогда он закроется. Нельзя ли это сделать из макроса?
 
я бы еще этот участок кода сделал бы без копирования и вставки
Код
1
2
3
4
wd2.Range.Copy                                                            
    wd1.Bookmarks.Item(bm2_name$).Range.Paste
' Наверное так, ну и в подобных случаях
wd1.Bookmarks.Item(bm2_name$).Range=wd2.Range
Изменено: B.Key - 16.11.2015 23:28:56
 
vadi61, до конца мое сообщение не осилили? Я там про DisplayAlerts писал
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
B.Key,
спасибо так лучше. И одновременно решился вопрос с этим
Цитата
vadi61 написал:
И мне надо вручную нажать на ДА или НЕТ - только тогда он закроется. Нельзя ли это сделать из макроса?

Не так, к сожалению, не получается. Текст копируется, а картинки нет
Изменено: vadi61 - 17.11.2015 00:01:22
 
Цитата
vadi61 написал:
решился вопрос с этим
Поэтому и писал
 
Цитата
vadi61 написал:
спасибо так лучше
А разве картинки так скопируются? Помнится, их тоже надо было переносить.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
The_Prist написал:
А разве картинки так скопируются? Помнится, их тоже надо было переносить.
Вы как всегда правы - картинки не копируются
Вернулся к старому варианту.
А свой вопрос решил так: поставил на форму переключатель отображать / не отображать Word. Стандартно - не отображать, а если снова проблема возникнет, тогда уж...
А в макрос внес
If wd_visible$ <> vbNullString Then wa.Visible = True
Изменено: vadi61 - 17.11.2015 00:05:41
 
Цитата
vadi61 написал:
а если снова проблема возникнет
И все же попробуйте вставить Application.DisplayAlerts = False. Настройка должна подавить сообщение об очистке буфера обмена и выполнить действие по умолчанию(очистку). Т.к. причина установлена и её можно проигнорировать без ущерба функционалу - можно уже и пробовать устранить.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Вставил, не помогло. Но проблема, описанная в первом сообщении осталась.
Я сейчас еще раз искусственно вызвал ошибку, пытаясь записать в открытый документ. Снял задачу (Word) в диспетчере задач. Вставил в макрос Application.DisplayAlerts = False. Не помогло. Снова снял задачу. Сделал Word видимым (wa.Visible = True) и снова запустил макрос. Появилось окно об ошибке. Я его закрыл (сказал продолжить). Создался документ, в который не вставилось ни одно значение из массива (а содержимое двух других шаблонов вставилось). Я его закрыл. и снова выполни макрос. Теперь все пошло без доп. запросов, но Word снова не заполнился вставками из массива. Я вставил в макрос в место заполнения массива MsgBox
   For i = 0 To tm_num%
       aText(i) = Range("H" & i + row_one%).Text
       MsgBox aText(i)
   Next i
оказалось массив имеет только первое значение, все остальные были пустыми. Я повторил процесс - значений было уже несколько. На четвертый раз все заработало и массив заполнился и в Word все вставилось. Я ничего не менял. Макрос сам заработал. Я понимаю, что какое-то объяснение есть, но я его не представляю.
Изменено: vadi61 - 17.11.2015 01:27:40
Страницы: 1
Читают тему
Loading...