Доброго дня всем. Прошу помощи знатоков разобраться в возникшей проблеме:
Есть большой проект, всё управление которым ведётся через PopUp меню. И всё работает отлично, кроме одного момента — при закрытии файла вылетает весь EXEL без сохранения других открытых файлов. Причём, если запускать макрос на закрытия кнопкой, то всё нормально, а если через меню, то косяк.
В прилагаемом файле воспроизведены сильно упрощённые фрагменты кода и при этом глюк остаётся.
Пробовал на разных машинах и разных версиях EXEL. Разницы нет.
Как мне увидеть ошибку? Что мне нужно сделать в файле, который вы выложили?
Файл я ваш взял, он у меня есть, больше можете не выкладывать его.
В файле есть кнопка, запускающая макрос "EXIT_file" и клик правой кнопкой мыши в любом месте таблицы вызывает PopUp меню, запускающее тот же макрос. При нажатии на кнопку макрос срабатывает штатно, а через меню, после закрытия файла вылетает EXEL.
Написал вам два письма на почту с заголовком "Письмо с Форума по VBA, Excel и Word". Написал именно на почту, а не на форум.
По идее есть нарушение логики.
Запускается процедура "Worksheet_BeforeRightClick", во время работы этой процедуры пользователь закрывает файл, в котором находится эта процедура, таким образом эта процедура обрывается.
Если закрывать другой любой файл, то ошибки нет.
Пока могу предложить только такой вариант: если макрос используется для любого файла, поместите макрос не в файл, а в надстройку.
В оригинальной программе именно так и есть. И макрос создания меню и макрос закрытия находятся вне исполняемого файла, только не в надстройке, а в PERSONAL. Трабл происходит и этом случае
Создайте ситуацию относительно Персонала, я у себя воссоздам.
Или свой Персонал скопируйте куда-нибудь, создайте новый Персонал, добейтесь, чтобы появлялась ошибка, и выложите этот Персонал на форуме.
ОК. Позже, при случае, сделаю.
По поводу "Worksheet_BeforeRightClick". Задумывался над этим ранее. Даже пытался сделать "ход конём" — чтобы не прерывать процедуру, результатам выбора меню на выход делал не закрытие файла, а присваивал значение переменной, которая отслеживалась и в случае положительного значения запускался макрос на выход. Увы, не сработало
Не вынесла душа поэта. Отвлёкся и сделал прямо сейчас
Не смогу помочь по этой теме - надо много смотреть.
Спросите на других форумах.
На этом форуме отвечаю только я.
Жаль. Спасибо за соучастие
Я позднее понял, что смысл не изменился от того, что вы поместили код в Персонал.
Контекстное меню вызывается по-прежнему из файла, который закрывается.
Пока макрос запускается из файла, который закрывается, так и будет ошибка.
Нужно событие "Worksheet_BeforeRightClick" запускать из другого места.
Для этого нужно создать класс и в нём событие "Worksheet_BeforeRightClick".
Пока других идей нет. Спросите ещё на других форумах, там много людей, может кто посоветует.
Если я создам класс в основном файле, то всё равно событие будет запускаться из закрываемого файла. Получается надо создавать его в персонале? Тогда я немного недопонимаю, как будет отслеживаться событие. Я с классами практически не работал.
На другом форуме пока молчат. Просмотров >300, но нет откликов.
Вот такое решение с использованием класса.
Как тестировать. Свой Персонал на время теста уберите, а этот Персонал используйте.
Поместите этот Персонал в соответствующую папку.
Затем откройте файл "Книга1.xlsb", щёлкните на листе правой кнопкой мыши, появится контекстное меню, щёлкните кнопку в этом контекстном меню, файл закроется.
В файле "Книга1.xlsb" макросов вообще нет.
Сейчас в Персонале в коде указано имя книги "Книга1" и имя листа "Лист1". На других книгах и листах контекстное меню появляться не будет.
Осталась проблема. Я с панелями инструментов и с контекстными меню очень редко что-то делаю, поэтому внутренние процессы не понимаю.
В модуле "КОНТЕКСТНОЕ_МЕНЮ" я окружил команду "Mbar.Delete" перехватчиком ошибок.
Если не открыто ни одной книги, кроме закрываемой книги, то ошибки нет.
Если открыта ещё какая-нибудь любая книга, то в этой команде происходит ошибка, т.к. в переменной Mbar то ли нет объекта, то ли ещё что-то, я в этом плохо разбираюсь.
Спасибо (и не только)
Мощное решение. Надо осваивать классы.
Теперь половину работ хочется переделать
При применении этого подхода, требуется добавить ещё одну фитчу. Я, так догадываюсь, опять нужно действовать через классы. Дело в том, что к этим макросам обращаются разные файлы, которые могут быть открыты одновременно. И теперь требуется, чтобы при их открытии персонал каким то образом это запоминал и делал проверку из полученного списка.
А если не заморачиваться с классами, а сделать процедуру, которая будет добавлять имя открываемого файла в коллекцию? Будет работать? Я просто сейчас не имею возможности проверить, а мысль работает :)
Классы в VBA очень редко используются, поэтому нет необходимости их осваивать.
Вот именно, чтобы работать с событиями объекта Application, нужно создать класс, т.к. другого варианта нет.
Вашу мысль не понял, т.к. я не знаю вашу ситуацию. Изучать вашу ситуацию я не смогу, т.к. у вас много кода, я много кода с ходу не осилю.