Excel это не сложно
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
20.04.2024, 01:06:09

Войти
Добавляйтесь в нашу группу ВКонтакте - будьте в курсе всех новых событий сайта, узнавайте первым обо всех акциях и новых статьях!
33 242 Сообщений в 5 457 Тем от 6 758 Пользователей
Последний пользователь: Сергей2662
*
Перейти на сайт Хитрости Надстройка MulTEx Обучающие тренинги Наша группа ВКонтакте
Правила форума Начало Помощь Поиск Календарь Войти Регистрация Выйти
+  Excel это не сложно
|-+  Основные форумы
| |-+  Вопросы по Word и VBA
| | |-+  После использования макроса не закрывается EXCEL
Страниц: [1]   Вниз
Печать
Автор Тема: После использования макроса не закрывается EXCEL  (Прочитано 17137 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Анатолий1958
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 3


Просмотр профиля
« : 12.08.2015, 10:14:00 »

Добрый день(вечер)!
Помогите пожалуйста решить следующую проблему.
При запуске Excel с использованием VBA из приложения WORD или любого другого приложения открывается Excel, выполняется всё что задумано и как бы всё хорошо.
Привожу пример: часть макроса WORD. При запуске макроса один раз всё происходит как и задумано. При запуске следующий раз вылетает по ошибке. Как удалось выяснить проблема возникает при использовании свойства Cells которое задаёт регион ячеек, при этом создаётся ещё один экземпляр Excel который не закрывается при выходе из приложения VBA. При замене выражения на
'Set xRange = MySheet.Range("A1:J10")
всё работает нормально. Но надо именно вариант
Set xRange = MySheet.Range(Cells(1, 1), Cells(10, 10))
так как только в нём есть возможность управлять ячейками программно.
Используется Office 2003, проверял в 2010 тоже самое.
   Кто знает как решить данную проблему пожалуйста помогите.

12.08.2015          С уважением Анатолий.

Перед использованием макроса не забываем подключить в References библиотеки
WORD и EXCEL. Лишнюю копию которая не закрывается смотрим в Диспетчере задач.

Код: (vb)
Sub HelpMe()
Dim CountColumns As Integer
Dim objExcel As Excel.Application
Dim excelApp As Workbook
Dim MySheet As Worksheet
Dim xRange As Excel.Range
Set objExcel = New Excel.Application
Set excelApp = objExcel.Workbooks.Add
Set MySheet = excelApp.ActiveSheet
'===============ПРОБЛЕМНЫЙ КОД===========================
'Для тестирования всех троих вариантов вышестоящую строку
'с кодом закоментируйте,а нижестоящую розкоментируйте
'*******************************************************
'Так создается лишняя копия EXCEL
Set xRange = MySheet.Range(Cells(1, 1), Cells(10, 10))
'И так тоже создается лишняя копия EXCEL
'Set xRange = Range("A1:J10")
'Так работает нормально
'Set xRange = MySheet.Range("A1:J10")
'===============ПРОБЛЕМНЫЙ КОД===========================
xRange.NumberFormat = "@"
For CountColumns = 1 To 10
    objExcel.ActiveSheet.Cells(CountColumns, CountColumns).Value = CountColumns
Next CountColumns
objExcel.Visible = True
objExcel.ScreenUpdating = True
'Нижерасположенные строки не оказывают
'влияния на уничтожение лишней копии Excel
Set xRange = Nothing
Set MySheet = Nothing
Set excelApp = Nothing
Set objExcel = Nothing
End Sub

Комментарий администратора Коды оформляем тегами - п.4.25 Правил форума
« Последнее редактирование: 12.08.2015, 10:49:38 от The_Prist » Записан
Surrogate
Пользователь
**

Репутация: +6/-0
Офлайн Офлайн

Сообщений: 94



Просмотр профиля WWW
« Ответ #1 : 12.08.2015, 10:38:45 »

Код: (vb)
'Set xRange = Range("A1:J10")
это явно глюконосный вариант. ибо у word тоже есть объект Range !
и еще вы забыли закрыть книгу и копию приложения
Код: (vb)
excelApp.Close savechanges:=True
objExcel.quit
« Последнее редактирование: 12.08.2015, 10:41:28 от Surrogate » Записан

Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #2 : 12.08.2015, 10:48:13 »

Уничтожать надо правильно - с закрытием приложения. Очистка ссылки на объект не закрывает приложение, а лишь высвобождает ячейку памяти, которая ссылается из Word на Вашу переменную. Перед очисткой надо закрыть:
Код: (vb)
objExcel.Quit

перед этим надо еще закрыть все открытые книги. В Вашем случае одну. Т.е. перед очисткой правильно делать так:
Код: (vb)
excelApp.Close 1 'закрываем книгу с сохранением. Но может появится запрос, т.к. книге не выбрано место хранения на диске. 0 - если закрыть без сохранения - тогда никаких запросов не будет и но и не ясно зачем все манипуляции с файлом...
objExcel.Quit

Ну и обращение к Range Excel-я без указания, что обращаетесь к Excel будет работать не так, как Вы предполагаете. xRange объявлен как Excel.Range, а по факту Вы пытаетесь ему присвоить значение объекта Range Word-а.

Почитайте на всякий случай - Как из Excel обратиться к другому приложению
может пригодится.

P.S. Тему переношу в ветку по Word, т.к. никакими багами тут не пахнет. Это всего лишь ошибки начинающего разработчика, который пока не достаточно хорошо понимает порядок обращения к объектам.
P.P.S. Коды следует оформлять тегами VB Code. В правилах об этом написано.
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Анатолий1958
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 3


Просмотр профиля
« Ответ #3 : 12.08.2015, 13:54:50 »

Код:
Спасибо большое за ответы, выполнил все рекомендации, но проблема осталась. Приведенный пример это только часть используемого кода, котрый частично упрощен для наглядности и понимания. Макрос запускается неоднократно и ровно столько же раз создается копий EXCEL. Важен просмотр полученного результата в каждой полученной копии, потом их можно закрыть без сохранения. Добавил в конец кода рекомендуемые строки:
[b]excelApp.Close 1
objExcel.Quit[/b]
но в диспетчере всё равно остаётся запущенная копия EXCEL это при использовании выражения
Set xRange = MySheet.Range(Cells(1, 1), Cells(10, 10))
при использовании выражения
Set xRange = MySheet.Range("A1:J10")
всё нормально. Выражение MySheet.Range(Cells(1, 1), Cells(10, 10)) создает ёщё одну копию EXCEL которую я не знаю как закрыть.
Записан
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #4 : 12.08.2015, 13:57:42 »

Set xRange = MySheet.Range(Cells(1, 1), Cells(10, 10))
А к чему, по-Вашему относятся здесь Cells? Вы не указали, что к листу Excel. А т.к. используете раннее связывание с Excel - то VBA ищет ближайшее откуда взять это для Range - новый экземпляр. Это и есть одна из неявных ошибок при неверном понимании работы с объектами разных приложений.
Правильно:
Код: (vb)
Set xRange = MySheet.Range(MySheet.Cells(1, 1), MySheet.Cells(10, 10))

Почитайте еще это, будет полезно: Как обратиться к диапазону из VBA
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Анатолий1958
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 3


Просмотр профиля
« Ответ #5 : 12.08.2015, 14:20:20 »

Огромное спасибо The_Prist!!! Всё заработало как и хотелоь!!! Просмотрел много литературы в бумажном и электронном виде, но нигде не видел что надо явно ссылатся на активный лист при использованиии объекта RANGE. Спасибо за ссылку с примерами.
С уважение Анатолий.
Записан
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #6 : 12.08.2015, 14:23:50 »

Спасибо за ссылку с примерами.
А Вы сходите в раздел Хитрости - я там много статей уже налепил. Может еще чего найдете ;-)
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Страниц: [1]   Вверх
Печать
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Яндекс.Метрика Рейтинг@Mail.ru