Открытие / активация документов Word в макросе VBA - PullRequest
10 голосов
/ 01 апреля 2009

Я надеюсь, что эксперт VB / VBA поможет мне. Учтите следующее: Пользователь открывает документ в Word 2003, и в макросе Normal.dot AutoOpen мы смотрим на текущий документ, и, если он был открыт путем нажатия на ссылку на веб-странице и соответствует определенным другим специфическим критериям приложения, закройте потоковое «копирование» и открытие исходного документа (найденного на общем диске, к которому мы можем предположить, что у пользователя есть доступ):

Documents.Open origDoc
Documents(ActiveDocument.FullName).Close SaveChanges:=wdDoNotSaveChanges
Documents(origDoc).Activate

With ActiveDocument
    ''# Do work
End With

Я думал, что мне нужно было позвонить Activate, чтобы убедиться, что исходный документ был ActiveDocument, но я получаю ошибку 4160 "Bad file name" при вызове .Activate. Если я закомментирую вызов .Activate, похоже, что ActiveDocument установлен для документа origDoc, даже если уже были открыты другие документы (я не совсем уверен, как управляется коллекция документов и как Word определяет что будет ActiveDocument, если вы программно закроете текущий ActiveDocument)

Итак, вызов .Open в документе явно устанавливает для документа значение ActiveDocument? Кроме того, вызывает ли .Activate в уже активном документе ошибку?

На самом деле я не смог найти много документации по этому поводу, поэтому заранее благодарен за любые предложения и понимание!

Ответы [ 4 ]

5 голосов
/ 04 декабря 2013

Простой ответ - да. Открывая документ с вашим кодом, вы делаете его активным документом, который затем закрываете в следующей строке и пытаетесь активировать в следующей, и это не удается, поскольку документ больше не открыт. VBA в целом, кажется, работает таким образом.

Важно быть осторожным с ActiveDocument, потому что не всегда очевидно, какие действия в коде или где-либо еще сделают документ «активным» (у меня нет никаких доказательств, но даже автосохранение может это сделать). Если есть какие-либо сомнения, вам лучше обратиться к документу через коллекцию Documents, хотя это также может привести к ошибкам, если документ больше не открыт, и вам, возможно, придется прибегнуть к итерации по коллекции, чтобы убедиться, что документ на самом деле, открытый. Я часто сталкиваюсь с этим в Excel VBA, и Word VBA в этом отношении функционирует одинаково.

Кроме того, VBA небрежно относится к освобождению объектов приложения. Если вы не будете осторожны, вы получите несколько процессов WINWORD, которые можно просмотреть в диспетчере задач, независимо от того, закрыли ли вы их или вышли из них в своем коде. Код, который я нашел, чтобы обойти это, сводится к моделированию процесса выбора END PROCESS в диспетчере задач. Это работает, но должно быть лучшее решение.

2 голосов
/ 03 августа 2013

Помните, что существует множество проблем, с которыми можно столкнуться:

  1. , если вы хотите повторно открыть документ после его закрытия один раз .... Word / Windows не делает 'отпустите' имя файла, и вы получите сообщение file busy 'или сообщение о создании ' временная копия '. Чтобы справиться с этой проблемой, мне пришлось разработать сложную систему создания / сохранения и приведение в порядок нескольких версий любых других документов, которые я открываю / манипулирую в своих приложениях Word из-за этой ошибки проектирования в методах Office Open / Close / Save.

  2. Используйте свойство ReadOnlyRecommended, установленное на False с .Open метод

  3. ссылка на объект документа (с именем doc, выше) может привести к серьезные ошибки, если вы не уверены что объект doc все еще существует до того, как вы попытаетесь им манипулировать. Всегда помни, что Word - это открытая прикладная платформа .... и пользователь может делать то, что вы не считали на ... в последнюю миллисекунду или около того. Этот совет распространяется на любой другой объект или имущество, которое вы можете хотите манипулировать в Word.

  4. если вы управляете коллекцией документов (или любой другой) без гарантируя, что документ или другой объект все еще там и действителен перед удалением или перемещением в коллекции, вы можете
    получить ошибки ' переполнение стека '. Особенно если вы попытаетесь закрыть / удалить объекты в коллекции, начиная с .item(1). Вы необходимо удалить элементы в коллекции из последнего и запомнить что подделки и указатели коллекции меняются всякий раз, когда вы .add / .remove / .Закрыть элементы из них.

1 голос
/ 20 мая 2009

Вы не должны использовать объект ActiveDocument во-первых, если это не является абсолютно необходимым, потому что это очень ненадежно. Предпочтительный подход будет следующим:

Documents(ActiveDocument.FullName).Close SaveChanges:=wdDoNotSaveChanges

Dim doc as Document
Set doc = Documents.Open(origDoc)        
With doc
    'Do work
End With
1 голос
/ 01 апреля 2009

У вас есть ошибка здесь:

Document(origDoc).Activate

Должен быть документ s .

Да, вы можете активировать активный документ. Тогда ничего не происходит.

Да, открытый документ становится активным. Если вы не уверены, используйте Documents.Open(origDoc).Activate.

...