Mam 2 skoroszyty Excela (po kilka arkuszu w kazdym), z których regularnie
korzystam w pracy, na komputerze w miejscu pracy. Często muszę też
popracować na nich po przyjściu do domu - i tu zaczyna się problem
przenoszenia plików. Ciągłe zgrywanie na CD lub jakiś dysk wymienny
codziennie jest troche nudne. Chciałbym tę procedurę troche ułatwić. Na obu
komputerach (praca, dom) mam zainstalowane Excel 2003, oba posiadają dostęp
do netu.
Myślałem o takim rozwiązaniu - aby stworzyć w obu skoroszytach Pasek
narzędziowy z dwoma guzikami (Wyślij i Pobierz).
Przycisk wyślij realizowałby następujące zadanie: zapisywał plik na dysku
skąd go otworzył, dodatkowo stworzył kopię (jak robi to funkcja
"Narzędzia/Opcje ogólne/Zawsze z kopią zapasową" w poleceniu "Plik/Zapisz
jako...") oraz tak zapisany skoroszyt wysłał na serwer FTP w określone
miejsce.
Przycisk pobierz realizowałby następujące zadanie. Po otworzeniu z dysku
lokalnego arkusza i wczytaniu do programu Excel wersji, ktorą mam na danym
komputerze wciskam "Pobierz" - guzik ten realizowałby pobranie z serwera FTP
wersji pliku, zapisał do na miejscu otwartego skoroszytu, otworzył go w
miejsce wczytanego arkusza do edycji i poinformował o powodzeniu tych
czynności.
Pisze ten post na te grupe ponieważ nie znam zupełnie VB, a wydaje mi sie
jednak że tylko ta droga moge uzyskać taki rezultat. Poprosiłbym o jakieś
sugestie. Co do FTP może być to zrealizowane przez Moje miejsca sieciowe
(czyli jakby przez system), lub za pomoca nawet systemowego narzedzia
ftp.exe, ktore zapewne można wywołać z określonymi parametrami (sam tak
robiłem ustawiajac wysyłanie i pobieranie pliku poprzez systemowy
Harmonogram zadań).
Myśalałem jeszcze o rarejestrowaniu makra, ale to wysyłanie na serwer
zupełnie nie wiem jak to wtedy zrealizować.
zdrawiam, cacup.
- - -
e-mail: cacup@[no-spam]stud.pam.szczecin.pl (wytnij [no-spam])
gg: 7213767
> Przycisk wyślij realizowałby następujące zadanie: zapisywał plik na dysku
> skąd go otworzył,
Tu musisz użyć metody Save:
ActiveWorkbook.Save
> dodatkowo stworzył kopię (jak robi to funkcja "Narzędzia/Opcje
> ogólne/Zawsze z kopią zapasową" w poleceniu "Plik/Zapisz jako...")
Możesz to zrealizować za pomocą metody SaveCopyAs obiektu Workbook:
ActiveWorkbook.SaveCopyAs "C:\Jakiś folder\Jakaś nazwa.xls"
> Co do FTP może być to zrealizowane przez Moje miejsca sieciowe (czyli
> jakby przez system), lub za pomoca nawet systemowego narzedzia ftp.exe,
> ktore zapewne można wywołać z określonymi parametrami (sam tak robiłem
> ustawiajac wysyłanie i pobieranie pliku poprzez systemowy Harmonogram
> zadań).
Jeśli chodzi i FTP, to tu masz przykład obsługi tego protokółu przy pomocy
VB:
http://www.answers.com/topic/ftp-functions
Ale jeśli znasz polecenia okna komendy to możesz użyć też funckji Shell. coś
w tym stylu:
Shell "ftp.exe -C:\Jakiś folder\Jakaś nazwa.xls .... - i jakieś tam komendy"
--
Pozdrowienia
pxd74
>> dodatkowo stworzył kopię (jak robi to funkcja "Narzędzia/Opcje
>> ogólne/Zawsze z kopią zapasową" w poleceniu "Plik/Zapisz jako...")
> Możesz to zrealizować za pomocą metody SaveCopyAs obiektu Workbook:
> ActiveWorkbook.SaveCopyAs "C:\Jakiś folder\Jakaś nazwa.xls"
Pobawilem sie troche rejestrowaniem makr i potem podgladalem je w edytorze.
VB to musi byc niesamowicie rozbudowane narzedzie, niestety nic w nim nie
kumam.
Zarejestrowalem makro w ktorym sobie zapisalem arkusz. Patrze w to makro i
mam tam:
ActiveWorkbook.SaveAs Filename:="C:\Pliki\praca\2007_kpir.xls", FileFormat _
:=xlNormal, Password:="", WriteResPassword:="",
ReadOnlyRecommended:= _
False, CreateBackup:=True
wlasciwie rozumiem co to jest, realizuje to moje 2 postulaty zadania: zapis
i stworzenie kopii. extra!
>> Co do FTP
> Jeśli chodzi i FTP, to tu masz przykład obsługi tego protokółu przy pomocy
> VB: http://www.answers.com/topic/ftp-functions
niestety, ale zbyt skomplikowane dla mnie :D
> Ale jeśli znasz polecenia okna komendy to możesz użyć też funckji Shell.
> coś w tym stylu: Shell "ftp.exe -C:\Jakiś folder\Jakaś nazwa.xls .... - i
> jakieś tam komendy"
tak, te skladnie poznalem bardzo dobrze, zrobilem tak uzyskujac zamierzony
efekt:
Shell "C:\WINDOWS\system32\ftp.exe -s:C:\Pliki\praca\ips_put_kpir.txt
stud.pam.szczecin.pl"
i tu naszla mnie taka refleksja, bo jak pisalem mam 2 pliki (skoroszytu), w
ktorych musialbym umieszczac makra, ktore wlasciwie robia to samo. wiaze sie
to z dwukrotnym uruchamianiem tych makr, w kazdym skoroszycie kolejno.
zauwazylem tez, ze excel podczas nagrywania marka moze zaczepiac to makro do
aktualnego otwartego skoroszytu (czyli tak jak to zrobilem), ale tez do
"osobistego skoroszytu makr - PERSONAL.XLS". Czy ten osobisty skoroszyt makr
jest jakby "nadzrzędny"? Moge umiescic tam polaczone makra z 2 skoroszytow i
wywolywac je jednokrotnie?
Zmierzam tym samym do drugiego zadania jakie chcialbym zautomatyzowac. Przy
otwartym pustym excelu ("...\excel.exe" /e) chce sciagnac z ftp oba pliki
skoroszytow na dysk a potem je otworzyc do edycji. ze zrozumialych wzgledow
nie moge tego zrobic makrem osadzonym w arkuszu bo nie jest on jeszcze
otwarty do edycji. czy tu wlasnie mam sie zainteresowac PERSONAL.XLS? Tu
osadzic to makro? Jakim poleceniem otworzyc skoroszyty do edycji?
i jeszcze jedno. drzewo katalogow na kopie w pracy i w domu jest identyczne.
przerzucane pliki zabieraja ze soba osadzone w nich makra i wydaje sie ze
takie makro jakie dotychczas stworzylem bedzie dzialac na jednym i na drugim
kompie. a co z makrami osadzonymi w PERSONAL.XLS? Bo stworzeniu takich makr
osadzonych w PERSONAL bede musial je przeniesc do Excela "po drugiej stonie
kabla". Jak to zrobic, gdzie szukac tego pliku PERSONAL.XLS?
narazie stworzylem w PERSONAL.EXE makro zapisujace pliki i kopie na dysk,
zamykajace skoroszyty i uruchamiajace ftp.exe, ktore to ladnie wysyla mi na
serwer:
Windows("2007_nfz.xls").Activate
ActiveWorkbook.SaveAs Filename:="C:\Pliki\praca\2007_nfz.xls",
FileFormat:= _
xlNormal, Password:="", WriteResPassword:="",
ReadOnlyRecommended:=False _
, CreateBackup:=True
ActiveWorkbook.Close
Windows("2007_kpir.xls").Activate
ActiveWorkbook.SaveAs Filename:="C:\Pliki\praca\2007_kpir.xls",
FileFormat _
:=xlNormal, Password:="", WriteResPassword:="",
ReadOnlyRecommended:= _
False, CreateBackup:=True
ActiveWorkbook.Close
Shell "C:\WINDOWS\system32\ftp.exe -s:C:\Pliki\praca\ips_put.txt
stud.pam.szczecin.pl"
patrze na to makro i mysle co mogloby nie zadzialac.
1. jesli nie ma otwartego ktoregos z tych skoroszytow - bedzie blad. zapewne
cos z "Jezeli" (jezeli Windows("2007_nfz.xls") nie jest otwarte, = fałsz to
Workbooks.Open Filename:="C:\Pliki\praca\2007_nfz.xls"). Dobrze kombinuje?
jak to zapisac po VB'owsku?
2. po wykonaniu shellowskiego ftp.exe chcialbym calkiem zamknac excela. da
sie to zrealizowac za pomoca VB?
3. podczas zapisu ActiveWorkbook.SaveAs Excel sie pyta czy nadpisac.
Chcialbym nadpisywac bez takiego zapytania. Da sie to zrealizowac?
kombinowalem tez juz z makrem w druga strone: sciagnac z ftp na dysk i
uruchomic do edycji:
Shell "C:\WINDOWS\system32\ftp.exe -s:C:\Pliki\praca\ips_get.txt
stud.pam.szczecin.pl"
Workbooks.Open Filename:="C:\Pliki\praca\2007_kpir.xls", UpdateLinks:=3
Workbooks.Open Filename:="C:\Pliki\praca\2007_nfz.xls", UpdateLinks:=3
uruchomic do edycji juz wyczailem. zainteresowalem sie UpdateLinks. Zapewne
chodzi o "polaczenia" pomiedzy oboma plikami skoroszytow. od razu nasuwa mi
sie takie pytanie: Podczas otwierania do edycji jeden z arkuszy sie pyta czy
zaktualizowac dane, ktore pobiera z drugiego. Zawsze biore "aktualizuj".
Mozna ten komunikat zautomatyzowac przez VB?
i druga chyba najpowazniejsza sprawa, przy ktorej sie zatrzymalem - Shell w
pierwszej linii. chce on pobrac pliki z ftp i zapisac na dysk. samo
polecenie dziala bez zarzutow, ale makro leci dalej i napotyka otwieranie z
dysku do edycji. i od razu otwiera... ale wersje plikow jeszcze nie
zaktualizowane przez ftp.exe ze Shella(zrozumiale, bo ten potrzebuje chwile
czasu na upload plikow). hmm, nasuwa mi sie mysl, czy ftp.exe po udanym
zakonczeniu swojego dzialania podaje cos na wyjsciu, co mogloby poinformowac
moje makro o tym, zeby zaczelo dalej dzialac otwierajac pliki juz po
zakonczonym sukcesem uploadzie?
Wogole dziekuje za pomoc i przepraszam ze pisze jak laik, ale VB to dla mnie
jest cos calkowicie nowego z czym nie mialem nigdy kontaktu.
--
Pozdrawiam, cacup.
[...]
> i druga chyba najpowazniejsza sprawa, przy ktorej sie zatrzymalem - Shell
> w pierwszej linii. chce on pobrac pliki z ftp i zapisac na dysk. samo
> polecenie dziala bez zarzutow, ale makro leci dalej i napotyka otwieranie
> z dysku do edycji. i od razu otwiera... ale wersje plikow jeszcze nie
> zaktualizowane przez ftp.exe ze Shella(zrozumiale, bo ten potrzebuje
> chwile czasu na upload plikow). hmm, nasuwa mi sie mysl, czy ftp.exe po
> udanym zakonczeniu swojego dzialania podaje cos na wyjsciu, co mogloby
> poinformowac moje makro o tym, zeby zaczelo dalej dzialac otwierajac pliki
> juz po zakonczonym sukcesem uploadzie?
[..]
Bo Shell jest wykonywany w sposób asynchroniczny.
Może uda Ci się w Twoim przykładzie uruchomić Shella w sposób synchroniczny.
w poniższy sposób:
http://www.bratki.w.v1.pl/accesspseudofaq/40a_OthShllFaq.htm#oth40a_02
--
Pozdrowienia
BraZby
tak tez wlasnie myslalem. wielkie dziekuje za podanie przykladu rozwiazania
problemu, ale za cholere nie wiem jak zaimplementowac przyklad w moim
makrze. poradzisz jak to zrobic?
[...]
>>................... zrobilem tak uzyskujac zamierzony efekt:
>> Shell "C:\WINDOWS\system32\ftp.exe -s:C:\Pliki\praca\ips_put_kpir.txt
>> stud.pam.szczecin.pl"
No to sprawdź, czy nie pójdzie tak:
Dim sCmdLine As String
sCmdLine = "C:\WINDOWS\system32\ftp.exe -s:C:\Pliki\praca\ips_put.txt
stud.pam.szczecin.pl"
' uruchom Shell'a
Call zbShellSynchroWin(sCmdLine, vbNormalFocus, True)
' i czekaj na zakończenie
MsgBox "Shell zakończony"
--
Pozdrowienia
BraZby
oczywiscie poszlo, nie chcialo wczesniej, bo poniewaz deklaracje
umieszczalem zawziecie wszedzie tylko nie na poczatku w (Declarations) :D
Wielkie luki w wiedzy mam niestety.
Ok, ostatnia rzecz jaka mnie doprowadzi do ekstazy :D to stworzenie wlasnego
paska narzędzi z dwoma guzikami, pod ktore podczepić chcialbym makra. tez
niestety poza moimi mozliwosciami jets to zadanie. czy do takiego paska moge
dodawac swoje ikonki? W jakim rozmiarze, formacie i glebi kolorow nalezy je
przygotowac?
przy okazji wroce do pytan z poprzednich moich postów:
1. jak sprawdzic, czy dokument jest otwarty w Excelu?
2. czy za pomoca VB mozna zamknac Excela?
3. zapis za pomoca ActiveWorkbook.SaveAs powoduje, ze Excel sie pyta czy
nadpisac plik istniejacy na dysku.
Chcialbym nadpisywac bez takiego zapytania. Czy da sie to zrealizowac?
Function isOpen()
Dim C As Window
'
isOpen = False
For Each C In Windows
If C.Caption = "Zeszyt1" Then
isOpen = True
Exit Function
End If
Next C
End Function
> 2. czy za pomoca VB mozna zamknac Excela?
???
> 3. zapis za pomoca ActiveWorkbook.SaveAs powoduje, ze Excel sie pyta czy
> nadpisac plik istniejacy na dysku.
> Chcialbym nadpisywac bez takiego zapytania. Czy da sie to zrealizowac?
Application.DisplayAlerts
a tak na marginesie, czy nie funkcjonalniej bybloby zestawic jakis VPN?
pozdrawiam
[...]
> Ok, ostatnia rzecz jaka mnie doprowadzi do ekstazy :D to stworzenie
> wlasnego paska narzędzi z dwoma guzikami, pod ktore podczepić chcialbym
> makra. tez niestety poza moimi mozliwosciami jets to zadanie. czy do
> takiego paska moge dodawac swoje ikonki? W jakim rozmiarze, formacie i
> glebi kolorow nalezy je przygotowac?
>
>
> przy okazji wroce do pytan z poprzednich moich postów:
>
[...]
> 2. czy za pomoca VB mozna zamknac Excela?
Spróbuj coś takiego:
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" (ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
lParam As Any) As Long
Private Const WM_CLOSE = &H10
Private Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long
'___________________________
Private Sub Command0_Click()
Dim hDsk As Long
Dim hExcel As Long
Dim hTmp As Long
hDsk = GetDesktopWindow
Do
hExcel = FindWindowEx(hDsk, ByVal hTmp, "XLMAIN", vbNullString)
If hExcel = 0 Then Exit Do
' Jeżeli arkusz będzie zmieniony, Excel będzie się pytał, czy
zapisać zmiany
SendMessage hExcel, WM_CLOSE, 0&, 0&
' użytkownik mógł anulować w oknie komunikatu
If IsWindow(hExcel) Then hTmp = hExcel
DoEvents
Loop
End Sub
--
Pozdrowienia
BraZby
> 1. jesli nie ma otwartego ktoregos z tych skoroszytow - bedzie blad.
> zapewne cos z "Jezeli" (jezeli Windows("2007_nfz.xls") nie jest
> otwarte, = fałsz to Workbooks.Open
> Filename:="C:\Pliki\praca\2007_nfz.xls"). Dobrze kombinuje? jak to
> zapisac po VB'owsku?
W tym wątku masz dwie funkcje sprawdzające czy dany skoroszyt jest otwarty:
http://groups.google.pl/group/microsoft.public.excel.programming/browse_frm/thread/a2b53486e2154d07/f60ca9d0cd8bff7b
> 2. po wykonaniu shellowskiego ftp.exe chcialbym
> calkiem zamknac excela. da sie to zrealizowac za pomoca VB?
Tak. Napisz:
Application.Quit
> 3. podczas zapisu ActiveWorkbook.SaveAs Excel sie pyta czy nadpisac.
> Chcialbym nadpisywac bez takiego zapytania. Da sie to zrealizowac?
Przed zapisaniem wstaw taką linię:
Application.DisplayAlerts = False
a po zapisaniu taką:
Application.DisplayAlerts = True
--
Pozdrowienia
pxd74
dosyc to skomplikowane, dodatkowa funkcja, dodatkowe niezrozumiale dla mnie
polecenia (przepraszam za moje betoniarstwo w tym temacie :D).
Zapytam moze inaczej:
Czy excel wie jakie ma wczytane w danej chwili skoroszyty?
Jesli tak, jak te nazwy wygladaja - czy to sa sciezki do plikow, czy tytuly
okien skoroszytow, czy moze podawana gdzies we wlasciwosciach skoroszytu
nazwa?
Excel moze zrobic prosciej zapytanie "jezeli nie jest otwarty skoroszyt X to
go otworz z c:\pliki\X.xls"?
Czy trzeba stosowac te dodatkowa funkcje IsFileOpen() z przykladu, np.
http://support.microsoft.com/support/kb/articles/Q138/6/21.asp ?
Moje obecne makro wyglada tak (zakładam w nim ze oba pliki 2007_nfz i
...kpir.xls sa otwarte w Excelu):
Windows("2007_nfz.xls").Activate
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs filename:="C:\Pliki\praca\2007_nfz.xls",
FileFormat:= _
xlNormal, Password:="", WriteResPassword:="",
ReadOnlyRecommended:=False _
, CreateBackup:=True
Application.DisplayAlerts = True
ActiveWorkbook.Close
Windows("2007_kpir.xls").Activate
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs filename:="C:\Pliki\praca\2007_kpir.xls",
FileFormat _
:=xlNormal, Password:="", WriteResPassword:="",
ReadOnlyRecommended:= _
False, CreateBackup:=True
Application.DisplayAlerts = True
ActiveWorkbook.Close
Tak jeszcze kombinuje tą drogą: a jakby Excela zmusic do zapisania
wszystkich otwartych skoroszytow w miejsca skad byly otwarte, bez pytania,
ktore sa otwarte (bo przeciez jezeli Y.xls nie byl otwarty, to nie ma sensu
go otwierac tylko po to zeby go ponownie zapisac - tak teraz sie zastanawiam
nad tym i zaczynam widziec jakis bezsens mojego dotychczasowego dzialania
:D). Podziwiam programistów, serio!!!
>> 2. po wykonaniu shellowskiego ftp.exe chcialbym
>> calkiem zamknac excela. da sie to zrealizowac za pomoca VB?
> Tak. Napisz: Application.Quit
działa!
>> 3. podczas zapisu ActiveWorkbook.SaveAs Excel sie pyta czy nadpisac.
>> Chcialbym nadpisywac bez takiego zapytania. Da sie to zrealizowac?
> Przed zapisaniem wstaw taką linię: Application.DisplayAlerts = False a po
> zapisaniu taką: Application.DisplayAlerts = True
tez dziala, co wiecej pomyslalem zeby Application.DisplayAlert "objąć"
otwieranie plikow, gdzie pyta o aktualizacje wartosci pol jednego skoroszytu
z innego - tez dziala :D
Application.DisplayAlerts = False
Workbooks.Open filename:="C:\Pliki\praca\2007_kpir.xls", UpdateLinks:=3
Workbooks.Open filename:="C:\Pliki\praca\2007_nfz.xls", UpdateLinks:=3
Application.DisplayAlerts = True
po prostu łał
> Zapytam moze inaczej:
> Czy excel wie jakie ma wczytane w danej chwili skoroszyty?
> Jesli tak, jak te nazwy wygladaja - czy to sa sciezki do plikow, czy
> tytuly okien skoroszytow, czy moze podawana gdzies we wlasciwosciach
> skoroszytu nazwa?
Oczywiście, że aplikacja Excela wie jakie są otwarte aktualnie skoroszyty
Excela w tej instancji aplikacji. Skoroszyty te nie są przechowywane w
postaci ścieżek, nazw czy czegoś takiego tylko w postaci obiektów typu
Workbook znajdujących się w kolekcji Workbooks. Aby sprawdzić czy dany plik
jest otwarty należy w pętli przejść po wszystkich elementach kolekcji
Workbooks i porównać jakąś właściwość każdego obiektu z żadaną nazwą. Od
widzimisie programisty zależy czy porównana będzie nazwa skoroszytu,
ścieżka, pełna nazwa czy może np. wartość komórki A1 w pierwszym arkuszu :-)
W tym wątku, który podałem w drugim poście jest przykład takiego kodu -
sprawdzana jest właściwość Name.
Wiem, że może to co napisałem powyżej jest dla Ciebie niezbyt zrozumiałe,
ale jeśli chcesz zrozumieć kod Visual Basic, to musisz wiedzieć co to
takiego obiekt, kolekcja, własciwość czy metoda.
> Excel moze zrobic prosciej zapytanie "jezeli nie jest otwarty skoroszyt
> X to go otworz z c:\pliki\X.xls"?
> Czy trzeba stosowac te dodatkowa funkcje IsFileOpen() z przykladu, np.
> http://support.microsoft.com/support/kb/articles/Q138/6/21.asp ?
No, ale to dotyczy innego przypadku, albo się nie rozumiemy. Zauważ, że
możesz mieć wiele instancji aplikacji Excela otwartych równoczesnie na tym
samym komputerze (np. poprzez menu Start -> Porgramy -> Microsoft Office ->
Microsoft Excel tworzysz nową instancję Excela). Aby sprawdzić jakie pliki
są otwarte w danej instancji wystarczy wybrać menu Okno albo otworzyć Edytor
Visual Basic -> tam każdy dokumnet bedzie pokazywany jako osoby projekt w
oknie "Project - VBA Project". Pracując w sieci LAN możesz mieć też
przypadek, że któś na innym komputerze otworzy plik znajdujacy się na Twoim
komputerze. Ten artykuł ze strony support.microsoft.com dotyczy wykrywania
otwarcia pliku przez jakąkolwiek instancję Excela znajdującą się na Twoim
lub innym komputerze. Wydaje mi się, że to nie jest Ci potrzebne, wystarczy
Ci sprawdzenie czy skoroszyt jest otwarty w ramamch bieżącej instancji
Excela. Podając link do tamtego wątku miałem na mysli raczej rozwiązanie
podane w drugim lub piątym poście. Ten drugi kod wykorzystuje obsługę
błędów.
(...)
> Tak jeszcze kombinuje tą drogą: a jakby Excela zmusic do zapisania
> wszystkich otwartych skoroszytow w miejsca skad byly otwarte, bez
> pytania, ktore sa otwarte (bo przeciez jezeli Y.xls nie byl otwarty, to
> nie ma sensu go otwierac tylko po to zeby go ponownie zapisac - tak
> teraz sie zastanawiam nad tym i zaczynam widziec jakis bezsens mojego
> dotychczasowego dzialania
Aby to wykonać musisz uzyć pętli przechdzącej po wszystkich elementach
kolekcji Workbooks i każdy z tych elementów zapisac używając metody Save.
więc i tak i tak musisz użyc pętli :-)
--
Pozdrowienia
pxd74