Проблема в следующем. Мой проект стартует с файла Авторизация. В нем в стандартном модуле объявлена переменная mуVyzov (мойВызов). После авторизации макросом автоматически открывается нужный основной рабочий файл Работы_Мастерская . Из него я открываю из моего меню (попап) MyShortcut1 нужные мне файлы. После завершении работы с файлом, я чаще всего должен автоматически вернуться в рабочий файл Работы_Мастерская. Однако есть файлы в которых я как бы "должен остаться". Для того чтобы я мог отследить нужно ли мне после работы с этим файлом вернуться или нет, я и сделал эту переменную. Однако не смотря на то, что она глобальная. В модуле СТРАНИЦЫ (sheets code) ВЫЗЫВАЕМОГО ФАЙЛА эту переменную ВБА не видит. Это стандартно? Или я что-то сделал не так?
Код
Option Explicit
Public myVyzov As Integer
' следующая процедура запускается из моего всплывающего меня myPopap из файла "Работы мастерская"
Sub Открыть_файл_Картотека() ' данная процедура в главном модуле проекта в файле Авторзация
' открытие из Работы_мастерская
Dim LastRow As Long
ChDir myDisk
On Error Resume Next
Set wb = Workbooks("Картотека".xlsm")
If Err.Number <> 0 Then
Workbooks.Open Filename:=myDisk & "\"Картотека".xlsm"
Workbooks("Картотека".xlsm").Sheets("Лист1").Visible = True
Workbooks("Картотека".xlsm").Sheets("Внимание").Visible = False
End If
With Workbooks("Картотека".xlsm").Sheets("Лист1")
LastRow = .Cells(.Rows.count, 1).End(xlUp).Offset(1, 0).Row
.Cells(LastRow + 1, 1).Activate ' чтобы последние данные были в зоне видимости
End With
myVyzov = 1
End Sub
А теперь код страницы Работа мастерская откуда я запускаю:
Код
Private Sub Worksheet_BeforeRightClick(ByVal Target As Excel.Range, Cancel As Boolean)
If Target.Column >= 1 And Target.Column < 8 Then
CommandBars("MyShortcut1").ShowPopup
Cancel = True
End If
If myVyzov = 0 Then ' VBA уже здесь не видит Паблик переменную. и при компиляции выдает ошибку.
'(Тогда я убрал в заголовке Option Explicit - перестал ругаться но значение стало Empty :)
Workbooks("Работа_Мастерская.xlsm").Worksheets("Лист1").Activate
End If
myVyzov = 0
End Sub
И код модуля книги Работа_мастерская
Код
Sub CreateShortcut1()
Dim myBar As CommandBar
Dim myItem As CommandBarControl
Call DeleteShortcut1
Set myBar = CommandBars.Add _
(Name:="MyShortcut1", Position:=msoBarPopup, Temporary:=True)
...
Set myItem = myBar.Controls.Add(Type:=msoControlButton)
With myItem
.Caption = "&Отрыть картотеку"
.OnAction = "Авторизация.xlsm!Открыть_файл_Картотека"
.FaceId = 767
End With
End Sub
Нашел у Вас на форуме в архиве ZVI написал, что глобальные переменный могут терять свои значения. Это получается тоже этот случай? Хотя не замечал, чтобы другие глобальные переменные терялись. Хотя программа еще толком не тестировалась. Но так вроде основные функции работают. Вернее - Я так глубоко еще не копал. Или ошибка у меня? Если мой случай подпадает под описание ZVI, то подскажите, как проще можно решить данную проблему - отследить нужно вернуться или нет без глобальной переменной. Заранее спасибо всем кто откликнется.
Разные книги - разные проекты- разные модули - разные переменные. Переменную и не должно быть видно. Глобальная переменная доступна только модулям одного проекта. Передавай значение через свойство книги, ячейку листа, реестр виндоуз и т.д.
у меня та же проблема! открыл Excel, VBE - и ни в одном модуле не видна Ваша переменная, хотя там, у себя, Вы ее вроде правильно обьявили... читайте тут: Understanding the Lifetime of Variables и смежные темы)
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
PowerBoy написал: Разные книги - разные проекты- разные модули - разные переменные. Переменную и не должно быть видно. Глобальная переменная доступна только модулям одного проекта.
У меня ВСЕ процедуры в ОДНОЙ книге - Авторизация.xlsm (В этой книге вообще нет никаких таблиц с данными - только макросы (процедуры) - очень удобно при обновлениях. Другие книги открываются макросами из Авторизация.xlsm . Все макросы этих книг вызывают макросы Авторизация.xlsm. Все глобальные переменные в этих макросах видны. Но кажется я понял что Вы имеете в виду. Макрос (процедура) книги Open, Activate в каждой книги не является макросом проекта. А макросом индивидуальной книги? Поэтому глобальные переменные в этих макросах и не видны? Кстати саму проблему я решил - в каждой книге прописал маленькие "промежуточные"процедуры вызова макроса из Авторизация и уже в них прописал - возвращаться в данную книгу или нет. Но хочется докопаться до сути - чтобы правильно понимать работу Эксель.
Ігор Гончаренко написал: читайте тут: Understanding the Lifetime of Variables и смежные темы)
Спасибо. Очень полезная инфа. Только я программировал (как любитель - небольшие программы на 4 БД) на вижуал фокспро. И с такими проблемами не встречался. Там, понятное дело, базы данных привязаны к одному проекту. А как мне сделать мои пять книг,(Авторизация, КартотекаПриборов, Сводная ведомость, РаботыМастерская и ДвижениеПриборов) чтобы они "ПОНИМАЛИ" что они в одном проекте?
vsahno написал: Однако не смотря на то, что она глобальная.
Не смотря для кого/чего? Что проект в Картотека.xlsm знает о проекте в Авторизация.xlsm? Правильно, ничего. Создайте ссылку на проект в Авторизация.xlsm к проекте Картотека.xlsm (Tools/References) тогда, код в Картотека.xlsm будет видеть общие переменные в Авторизация.xlsm. Успехов.
предполагается, что файлы Авторизация, КартотекаПриборов, Сводная ведомость, РаботыМастерская и ДвижениеПриборовнаходятся находятся в той же папке в которой будет сохранен файл с макросами приведенными ниже (макроса скопируйте в файл, фалй сохранике в папку, в которой находятся вышеназванные файлы)
Код
Function CheckOrOpen5WBs()
Dim ar, i&, wb As Workbook, fn$
ar = Array("Авторизация", "КартотекаПриборов", "Сводная ведомость", "РаботыМастерская", "ДвижениеПриборов")
For i = LBound(ar) To UBound(ar)
For Each wb In Workbooks
If wb.Name Like ar(i) & "*" Then Set ar(i) = wb: Exit For
Next
If TypeName(ar(i)) = "String" Then
fn = Dir(ThisWorkbook.Path & Application.PathSeparator & (i) & ".xls*")
If fn <> "" Then
Set ar(i) = Workbooks.Open(ThisWorkbook.Path & Application.PathSeparator & fn)
Else
MsgBox "В папке:" & vbLf & ThisWorkbook.Path & Application.PathSeparator & vbLf & _
"не найден файл:" & vbLf & ar(i), vbCritical, "Аварийная остановка. Не найден обязательній файл!!!"
End
End If
End If
Next
CheckOrOpen5WBs = ar
End Function
Sub Test()
Dim wbs, i&
wbs = CheckOrOpen5WBs
For i = LBound(wbs) To UBound(wbs)
MsgBox wbs(i).Name & " закрывается..."
wbs(i).Close False
Next
End Sub
если верхняя функция сработает без проблем - то в макросе Test Вы получите массив wbs, содержащий: wbs(0) = книга Авторизация, wbs(1) = книга КартотекаПриборов, wbs(2) = книга Сводная ведомость, wbs(3) = книга РаботыМастерская, wbs(4) = книга ДвижениеПриборовнаходятся которые были присвоены или открыты в CheckOrOpen5WBs по итогу работы макроса все книги будут закрыты.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
С.М. написал: Есть функция Application.Run , которая "находит" макросы в файлах других проектов (книг), без создания ссылок Tools->References.
Все книги действительно в одной папке. Я вызываю макросы (процедуры) из файла "Авторизация" (они все в глобальном модуле - он один) простым например: "Авторизация!.xlsm!PoiskZakaza" А если в коде формы, которая ВСЕГДА отрывается из книги-модуля, просто Call PoiskZakaza. Все формы и их коды также прописаны в файле Авторизация. Поэтому у меня не было проблем с глобальными переменными. Единственное чего я не учел - что сам файл при открытии действительно "не знает" что его открыли из проекта и при инициализации и/ или активации никакие глобальные переменные не видит. А вот то что посоветовал Андрей - должно, я думаю, помочь.
Цитата
Андрей VG написал: Создайте ссылку на проект в Авторизация.xlsm к проекте Картотека.xlsm (Tools/References) тогда, код в Картотека.xlsm будет видеть общие переменные в Авторизация.xlsm.
Спасибо! Попробовал - ругается, собака, на конфликт имен! Все равно всем спасибо, я думаю, что подсказак Андрея VG, все равно должна решить проблему!
Ігор Гончаренко написал: по итогу работы макроса все книги будут закрыты
Игорь, Вам отдельное спасибо, но это не выход. Разным пользователям - у механиков, например, нет прав на открытие книги ДвижениеПриборов. Да и зачем, Они при открытии файла авторизация, пройдя по личному паролю, попадают в нужный им файл РаботыМастерская. Им больше для своей работы ничего и не нужно. Стояла задача - после работы макроса в файле КартотекаПриборов (ПродлениеГгарантии) (А макрос вызывается из ПопапМеню) - вернуться назад в файл РаботыМастерская. Если же макрос ПродлениеГарантии вызывается менеджером из файла ДвижениеПриборов вернуться назад в файл ДвижениеПриборов. А инициализация ПопапМеню происходит в файле(Книге) РАботыМастерская! И в момент открытия этой самой книги РаботыМастерская (а у менеджеров в ДвижениеПриборов) оказывается нельзя пользоваться глобальными переменными. Я уже написал, что решил проблему. И отвечаю Вам, потому, что Вы нашли время для меня, и пытались помочь. Вообще Ваш форум классная вещь. Я в нем прошел прекрасную школу. Спасибо создателям и модераторам. Вы делаете прекрасное дело. Когда стану профи, (если стану) обязательно присоединюсь к Вам и буду помогать другим "чайникам"
Я уже написал, что решил проблему. И отвечаю Вам, потому, что Вы нашли время для меня, и пытались помочь. Вообще Ваш форум классная вещь. Я в нем прошел прекрасную школу. Спасибо создателям и модераторам. Вы делаете прекрасное дело. Когда стану профи, (если стану) обязательно присоединюсь к Вам и буду помогать другим "чайникам"
vsahno написал: Попробовал - ругается, собака, на конфликт имен!
Возможно, у вас имена VBA проектов в книгах имеют одинаковое имя. Для переменных одинаковой области видимости нужно описывать путь в пространстве имён, чтобы VBA понимал, какую переменную или константу использовать ИмяПроекта.ИмяМодуля.ИмяПеременной. То же касается и одинаково названных методов и функций.