PDA

Показать полную графическую версию : [решено] Проверка значения переменной wBook


corbis
14-08-2015, 19:57
Задача такая:
Из одной книги перебрасываем данные в другую. Переброс может быть разовым или многоразовым.
Для этого есть кнопка, при нажатии на которую происходит копирование некоторых ячеек в активной строке.
Нужно проверить открыта ли вторая книга. Если открыта, то проверить: открыта она пользователем или из кода VBA.
Если пользователем, то просим закрыть (вдруг там данные нужные какие не сохранены), если из кода (значит, переменная уже инициализирована wBook = ActiveWorkbook ), тогда копируем.

Function IsBookOpen(wbFullName As String) As Boolean
Dim iFF As Integer
iFF = FreeFile
On Error Resume Next
Open wbFullName For Random Access Read Write Lock Read Write As #iFF
Close #iFF
IsBookOpen = Err
End Function

Private Sub Button_Click()
flag = 0

If (IsBookOpen("C:\test.xlsx")) Then
If wBook *не знаю, что тут проверить* Then
MsgBox ("Закрой test'")
Else
MsgBox ("Можно копировать")
End If

Else
Workbooks.Open Filename:="C:\test.xlsx"
Set wBook = ActiveWorkbook
End If
End Sub

NickM
14-08-2015, 20:50
А если обойтись без проверки? Просто вывешивать сообщение, что книга будет закрыта с сохранением всех внесенных изменений, ожидать несколько секунд и в коде закрывать сохраняя изменения.

corbis
14-08-2015, 20:52
а как закрыть книгу из кода, которую отрыл пользователь из проводника?

NickM
14-08-2015, 21:26
Хмм, озадачили. Если смотреть на Ваш код, то проверка открытия как бы намекает, что книга может быть открыта из общего доступа с любого компьютера сети. Тогда, исходя из этого закрыть приложение на др. компьютере не получиться по причине того, что определить его не представится возможным.
С др. стороны возможно узнать имя пользователя открывшего общую/расширенную книгу и уже пользователю направить сообщение с помощью того же net send(msg), который в корпоративной/доменной сети доставит его в сеанс пользователя.

corbis
14-08-2015, 21:51
Не совсем то, что требуется. Вроде обманул, только не знаю, насколько грамотно такое решение:

Public wBook As Workbook

Function IsBookOpen(wbFullName As String) As Boolean
Dim iFF As Integer
iFF = FreeFile
On Error Resume Next
Open wbFullName For Random Access Read Write Lock Read Write As #iFF
Close #iFF
IsBookOpen = Err
End Function

Private Sub Button_Click()
flag = 0

If (IsBookOpen("C:\test.xlsx")) Then

If VarType(wBook) <> 9 Then
MsgBox ("Закрой test'")
Else
MsgBox ("Можно копировать")
End If

Else
Workbooks.Open Filename:="C:\test.xlsx"
Set wBook = ActiveWorkbook
End If
End Sub

NickM
14-08-2015, 22:32
corbis, извините Меня, но смогу подержать Вас только теорией.
Ситуацию вижу так: определиться каким образом открыта книга:
1. Локально, в единственном сеансе пользователя - тогда и решение простое. Ввиду того, что в сеансе у приложения Эксель может быть одновременно открыта одна единственная книга/файл с одинаковым именем независимо от пути, то просто закрыть книгу по имени с сохранением внесенных изменений;
2 и 3. Книга открыта в терминальной сессии и/или с др. компьютера сети как книга общего доступа. Тут уже сложнее. Здесь придется с помощью кода VBA узнать имя пользователя/пользователей работающих с книгой, после с помощью системных, сторонних утилит(например от sysinternals) определить сессию/компьютер на котором залогинен пользователь занявший книгу, которому в последствии отправить сообщение. Также следует учесть/отвести время на реакцию пользователя после чего, при неисполнении требуемого действия предусмотреть возможность принудительного закрытия книги. А вот тут еще один момент - с помощью системных, сторонних утилит приложение в сессии/на удаленном компьютере можно просто "кильнуть", но ессно о никакой сохранности речи не идет, если сохранность нужна по зарез можно и заморочиться и реализовать ее.

corbis
15-08-2015, 21:10
Нашёл толковый способ, может пригодится кому

Dim wBook As Workbook
Set wBook = GetObject(ПутьКфайлу)

If Windows(wBook.Name).Visible = False Then
Windows(wBook.Name).Visible = True
End If


Если книга открыта, тогда просто с ней работаем. Если была закрыта - открываем и делаем её видимой.
Почему-то по дефолту она скрыта.

NickM
15-08-2015, 23:26
corbis, толковый в каком смысле?

corbis
16-08-2015, 03:17
Без всяких выдумывании. Одной командой решается поставленная задача.




© OSzone.net 2001-2012