Переход между книгами при активной UserForm VBA

Весь MS Office, программирование на Visual Basic for Applications и MS VB

Модератор: Naeel Maqsudov

vint
Сообщения: 37
Зарегистрирован: 19 мар 2009, 16:53

Не знаю, может вопрос глупый но я в затупе!
Есть база, при открытии книги запускается форма (их там много).
В эти формы по мере необходимости надо заносить (копировать) из различных excel документов данные . Но при активной UserForm нет никакой возможности не то что бы запустить но и даже активировать раннее открытый другой excel файл.
есть ли выход :confused:
Аватара пользователя
EducatedFool
Сообщения: 197
Зарегистрирован: 06 апр 2008, 14:03
Откуда: Россия, Урал
Контактная информация:

У формы есть свойство ShowModal
Значение этого свойства по умолчанию - TRUE
Установите это свойство в FALSE, и проблема исчезнет.
Макросы для Excel, Word, CorelDRAW. Быстро, профессионально, недорого. http://ExcelVBA.ru/

Благодарности принимаются на кошелёк WebMoney: R318574877619 и Яндекс.Деньги: 41001335672216
vint
Сообщения: 37
Зарегистрирован: 19 мар 2009, 16:53

Точно !!!
Спасибо большое!- не знал!!
Теперь другая проблема, появился доступ к листам самой базы- а это не хорошо.Я специально поставил на всех формах запрет закрытия по крестику и пароль который убирается со всех листов книги при открытии книги(чтобы не мешал работе макросов) и одновременном запуске главной формы а при закрытии (закрыть можно только с главной) происходит установка пароля на все листы и автозакрытие книги. Таким образом я не давал возможность юзеру попасть на листы этой базы, даже если он в момент запуска отключит макросы можно только полистать листы - пароль снят не будет. Тоесть в Вашем предложенном варианте появляется доступ к листам базы тогда когда уже пароль снят и там можно накуралесить делов тока держись - кладовщицы народ шустрый ;) .
Наверно в таком случае мне надо подумать над другим способом защиты листов базы, чоб макрос работал а ручки нет.
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

А как на счет скрытых листов.
На тулбаре "Элементы управления" есть кнопка "Свойства".
Стоя на листе в свойстве Visible можно установить значение 2, и тогда лист нельзя будет сделать видимым даже при помощи Формат/Лист/Показать (только из редактора VBA)
Тогда может и заморочки с паролями не понядобятся?
vint
Сообщения: 37
Зарегистрирован: 19 мар 2009, 16:53

Спасибо!
Мысль конешно интересная но как это сделать в моём случае?
число листов в базе колеблется в районе 200 и самое интересное их число непрерывно (в процессе работы с базой) изменяется программно, как добавляются так и удаляются, а пользователь видит только первый лист за формой которому я просто поставил зелёный фон и ярлычки от листов которые он не может активировать(поэтому он и не видит что происходит на рабочих листах). Если бы это сделать как с установкой/снятием паролей одновременно на все листы сколько бы их там не было который я использую

Код: Выделить всё

Sub ProtectAllSheets()
'защищаем все листы
Dim Sh As Worksheet
    For Each Sh In ThisWorkbook.Sheets
        Sh.Protect Password:="*****", Contents:=True, Scenarios:=True, UserInterfaceOnly:=True
    Next
    MsgBox "Все листы защищены!", vbInformation, "Защита"
End Sub
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

Нет ничего проще

If Sh.Index>1 then Sh.Visible=2

... и спрятали всё, кроме первого
vint
Сообщения: 37
Зарегистрирован: 19 мар 2009, 16:53

Действительно! Что то я протупил.
но теперь другое, иногда программе надо выбрать лист (например перед загрузкой диапазона в комбобокс из 6 колонок), метод селект завершен неверно, наверно надо перед этим на время делать так Sh.Visible=-1 а потом Sh.Visible=2
Я на верном пути ? Или есть другой выход?
Большой спасибо за помощь!
Аватара пользователя
EducatedFool
Сообщения: 197
Зарегистрирован: 06 апр 2008, 14:03
Откуда: Россия, Урал
Контактная информация:

Или есть другой выход?
Для подобных задач можно придумать несколько вариантов реализации.

В данном случае, многое зависит от того, как Вы заполняете комбобокс.
Если макросом считываете значения с листа, и по-одному записываете в комбобокс, - то отображать лист не требуется.

А чтобы впредь никогда не видеть подобных сообщений:
метод селект завершен неверно
полностью откажитесь от использования методов Select и Activate в своём коде.
В 95 % случаев их использование не требуется, и только замедляет выполнение кода.

В любом случае, для записи в комбобокс использование метода Select не требуется.
Макросы для Excel, Word, CorelDRAW. Быстро, профессионально, недорого. http://ExcelVBA.ru/

Благодарности принимаются на кошелёк WebMoney: R318574877619 и Яндекс.Деньги: 41001335672216
vint
Сообщения: 37
Зарегистрирован: 19 мар 2009, 16:53

Комбобокс из 6 столбцов заполняется методом RowSource, вот например один из кусков кода чтоб на пальцах не объяснять

Код: Выделить всё

Dim posstr As Variant 'переменная для непустого диапазона данных от А1 до F-неизвестно

iRow21 = 1    'начальная строка поиска
iRow22 = 1    'начальная строка если пустая 1-ая строка
While (Application.ActiveWorkbook.Worksheets("ТМЦ").Range("A" & iRow21).Value <> "")
iRow21 = iRow21 + 1
iRow22 = iRow21       'нашли первую пустую строку
Wend                  'значит последняя непустая строка на 1 меньше

iRow23 = iRow22 - 1   'вот она последняя непустая строка для раннее F-неизвестного

posstr = "A1" & ":" & _
Application.ActiveWorkbook.Worksheets("ТМЦ").Range("F" & iRow23).Address(False, False)

cmbNaim2.ColumnCount = 6    'загружаем 6 колонок для комбобокс
'Worksheets("ТМЦ").Select    'активируем необходимый лист перед загрузкой в комбобокс
cmbNaim2.RowSource = posstr 'загружаем комбобокс согласно полученной переменной
Worksheets("База").Select   'возврат на 1-ый лист
и если законспектировать селект как в коде , то соответственно он находит нужные данные а загружает этот диапазон с пустого не скрытого листа "База" и в итоге комба содержит около 200 пустых строк.
Я с Вами полностью согласен

Код: Выделить всё

полностью откажитесь от использования методов Select и Activate
всегда пытаюсь исключать подобное ( это сильно тормозит работу кода) но в данном случае я не знаю как поступить
и вот тут тоже

Код: Выделить всё

'сортируем лист "КР" по колонке "C" с ФИО
Worksheets("КР").Activate
    Columns("A:A").Select
    Range("A1:IV5000").Sort Key1:=Range("C1"), Order1:=xlAscending, Header:= _
    xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
    DataOption1:=xlSortNormal
    Range("A1").Select      'эстетические операции
Worksheets("База").Activate 'эстетические операции
Аватара пользователя
EducatedFool
Сообщения: 197
Зарегистрирован: 06 апр 2008, 14:03
Откуда: Россия, Урал
Контактная информация:

Код: Выделить всё

Private Sub UserForm_Initialize()
    cmbNaim2.ColumnCount = 6  
    With Worksheets("ТМЦ")
        Dim ra As Range: Set ra = .Range(.[a1], .Range("A" & .Rows.Count).End(xlUp)).Resize(, 6)
        [B]Me.cmbNaim2.List = ra.Value[/B] ' заносим весь массив в комбобокс
    End With
End Sub
И никаких Select-ов...
Лист "ТМЦ" при этом может быть скрытым.

Сортировку тоже можно оптимизировать - для этого совсем не обязательно активировать обрабатываемый лист.
Макросы для Excel, Word, CorelDRAW. Быстро, профессионально, недорого. http://ExcelVBA.ru/

Благодарности принимаются на кошелёк WebMoney: R318574877619 и Яндекс.Деньги: 41001335672216
Ответить