Centrum Skryptów - Microsoft Office

Jak mogę określić, czy skoroszyt programu Excel jest otwarty, a jeśli nie – otworzyć go? Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak mogę określić, czy skoroszyt programu Excel jest otwarty, a jeśli nie – otworzyć go?

Cześć, Skrypciarzu! W jaki sposób mogę określić, czy dany skoroszyt programu Excel jest otwarty i, jeśli nie jest, otworzyć go?

-- Paweł

Cześć, Pawle. Czasem dostajemy takie pytania, że wydaje nam się, iż moglibyśmy odpowiedzieć na nie w parę minut i potem zająć się pałaszowaniem wielkiego lunchu. Właściwie to powinniśmy już być na tyle mądrzy, by wiedzieć, że zawsze kiedy wydaje nam się, że jakiś problem nie jest żadnym problemem, kończy się tym, że w ogóle nie mamy czasu na lunch. Ale nie, my nigdy nie zmądrzejemy, i dlatego ciągle jeszcze siedzimy w biurze wymyślając rozwiązanie.

No cóż, zamiast lunchu będzie kolacja.

Jak się zatem stało, że się tak nabraliśmy? No cóż, wiemy, że Excel posiada kolekcję Workbooks (skoroszyty), która zwraca listę wszystkich otwartych skoroszytów. W swojej naiwności uznaliśmy, że idzie o wszystkie otwarte skoroszyty.

Niestety jednak okazało się, że kolekcja Workbooks działa tylko w odniesieniu do jednego wystąpienia programu Excel; oznacza to, że niemożliwe byłoby utworzenie nowego wystąpienia Excela i pobranie listy wszystkich otwartych skoroszytów. Musimy zatem połączyć się z każdym uruchomionym wystąpieniem, wysłać zapytanie o kolekcję Workbooks, po czym połączyć je wszystkie, tworząc jedną listę. Teoretycznie możliwe, ale jest pewne ale…

Poszliśmy więc po rozum do głowy: „Mamy kłopot z Excelem. Co ludzie robią, mając problem z Excelem?” Kiedy spojrzeliśmy na to z tej strony, odpowiedź nagle była jasna: użyjemy Worda aby wydostać się z opałów.

Tak, Microsoft Word. Jak się okazuje, Word posiada kolekcję o nazwie Tasks (zadania), która jest w stanie pełnić podobne funkcje, co Menedżer zadań Windows. (Więcej informacji o kolekcji Tasks znaleźć można w artykule „Build Your Own Task Manager Using Microsoft Word” (j.ang.) w centrum Scripting for Microsoft Office (j.ang.).) Jak widzimy poniżej, otwarte skoroszyty wyświetlone są (według nazwy pliku) w Menedżerze zadań:

Menadżer zadań Windows

Wpadliśmy więc na pomysł, że można użyć kolekcji Tasks, aby sprawdzić czy dany skoroszyt jest otwarty i otworzyć go, jeśli nie jest. W ten sposób powstał taki oto objazd, jeden z najdziwaczniejszych w historii Skrypciarzy:

Set objShell = CreateObject("Wscript.Shell")



Set objWord = CreateObject("Word.Application")

Set colTasks = objWord.Tasks

i = 0



For Each objTask in colTasks

    strName = LCase(objTask.Name)

    If Instr(strName, "inventory.xls") Then

        i = 1

    End If

Next



strCmdLine = "excel.exe " & chr(34) & "C:\Scripts\Inventory.xls" & chr(34)



If i = 0 Then

    objShell.Run strCmdLine, 3

End If



objWord.Quit

Skrypt zaczyna się niepozornie; tworzymy po prostu wystąpienie obiektu WSH Shell (będziemy go potem mogli użyć do otworzenia skoroszytu, jeśli okaże się to konieczne). Następnie tworzymy wystąpienie obiektu Word.Application i używamy właściwości Tasks, by pobrać kolekcję zadań uruchomionych na komputerze. (Zadania to wszystko, co widać w zakładce Aplikacje w Menedżerze zadań.) Ustawiamy również wartość zmiennej o nazwie i na 0 – za chwilę wyjaśnimy, dlaczego.

Teraz przechodzimy przez kolekcję zadań. Pobieramy zadanie i przechowujemy je (z nazwą zapisaną małymi literami) w zmiennej o nazwie strName; to właśnie robimy tu:

strName = LCase(objTask.Name)

Następnie używamy funkcji InStr języka VBScript, aby sprawdzić, czy ciąg inventory.xls pojawia się w nazwie zadania. Jeśli tak, to skoroszyt Inventory.xls jest już otwarty, a wartość zmiennej i ustawiamy na 1. Jeśli nie, to skoroszyt Inventory.xls nie jest otwarty, a zmienna i nie zmienia wartości z 0. Następnie sprawdzamy w ten sposób wszystkie zadania.

Kiedy zakończymy sprawdzanie zadań, sprawdzamy wartość zmiennej i. Jeśli jest ona równa 0, robimy dwie rzeczy. Najpierw tworzymy rozkaz wywołujący Excel.exe, jako parametr wiersza poleceń podając ścieżkę do pliku Inventory.xls. Tym zajmuje się poniższy fragment:

strCmdLine = "excel.exe " & chr(34) & "C:\Scripts\Inventory.xls" & chr(34)

Teraz używamy metody Run by wykonać nasz rozkaz. Oprócz rozkazu, podajemy metodzie Run jeden dodatkowy parametr, mianowicie wartość 3, o znaczeniu „Otwórz plik w zmaksymalizowanym oknie, po czym przełącz się na to okno”. Następnie wywołujemy metodę Quit by zamknąć Microsoft Word (który zresztą nie pojawia się w ogóle na ekranie) i zajmujemy się własnymi sprawami.

Tak tak, wiemy, jak to wszystko dziwacznie wygląda, ale gwarantujemy, że będzie działać. Przyznajemy jednak, że skrypt nie jest w pełni odporny na szkodliwe działania użytkowników: kolekcja Tasks wychwytuje jedynie nazwy plików, nie zaś całe ścieżki dostępu. Może więc powstać problem, jeśli otwarty będzie plik D:\Archive\Old Inventory Files\January 2004\Inventory.xls; skrypt znać będzie jedynie nazwę pliku (Inventory.xls) i uzna, że otwarty jest skrypt C:\Scripts\Inventory.xls. Sądzimy że istnieje sposób, by poradzić sobie z tym problemem, ale z jego rozwiązaniem musimy poczekać na inną okazję.

 Do początku strony Do początku strony


Centrum Skryptów - Microsoft Office