Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

VBA wyłączanie otwartego pliku

28 Sty 2019 15:47 567 17
  • Poziom 4  
    Witam,
    sytuacja wygląda tak:
    stworyzłem makro, które na samym końcu zapisuje plik w pewnej lokalizacji i tą nazwę wpisuje w komórkę jednego ze skoroszytów.
    Chciałbym wykorzystując nazwe pliku, która jest wpisana w koroszycie wyłączyć dany plik. Moje makro wygląda następująco:

    Sub usuwanie()

    Dim plik As Variant

    plik = Workbooks("plik główny.xls").Sheets("dane").Range("W4")

    plik.Close

    End Sub

    WYskakuje mi błąd:
    Run-time '424':
    Object required

    i nie wiem co robię źle.. Prosze o pomoc..
  • Poziom 34  
    Jakoś dziwnie to robisz ten 'plik główny.xls' w nim jest to makro?
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
  • Poziom 4  
    Wiem, że może ten kod nie był idealny, ale niestety clubs Twoja propozycja też nie działa. Rezultatem jest błąd :

    Run-time error'9'9:
    Subscript out of range

    Może przybliżę bardziej makro, które napisałem.
    Makro ma za zadanie otwarcie pliku "matki" do którego kopiuje pewne dane, następnie zapisuje go pod odpowiednia nazwą w odpowiedniej lokalizacji.
    Chodzi o to, że po uruchomieniu makra takich operacji ma do wykonania kilkadziesiąt. I cały czas zostaja mi otwarte nowo utworzone pliki, które zapisało. Próbowałem już różnych komend, by zamknąć te pliki, ale nic nie działa i wpadłem na pomysł, żeby spóbować zakmnąć je korzystając z pełnej nazwy pliku , która będzie w jakiejś komórce ( tonący brzytwy się chwyta).

    Poniżej jedna z opcji jakie testowałem:

    Kod: vbscript
    Zaloguj się, aby zobaczyć kod


    Najśmieszniejze jest to, że wcześniej w makrze otwieram jeszcze jeden plik z którego są kopiowane niektóre dane do pliku matki i bez problemu go zamykam komendą:
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
  • Poziom 22  
    To wejdź w debugger i pobadaj co masz w zmiennej plik. Stawiam na Nothing. Jeżeli tak to pobadaj dlaczego: co jest podane jako indeks Workbooks, czy taki plik masz aktualnie otwarty?
  • Poziom 34  
    Marco228 napisał:
    tą nazwę wpisuje w komórkę jednego ze skoroszytów

    clubs napisał:
    ale niestety clubs Twoja propozycja też nie działa

    Rozumiem że tą nazwę pliku zapisuje do komórki 'Range("W4")' razem z rozszerzeniem?
    bo jeżeli nie to
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
  • Poziom 4  
    Clubs: Tak, w komórce W4 jest cała nazwa pliku razem z rozszerzeniem.

    kinggustav: Tak jest Nothing.

    Spróbowałem teraz wykonać prosta operację kopiowania wykorzystując nazwę pliku z komórki, ale nie działa. Wyskakuje błąd:
    Run-time error'9'9:
    Subscript out of range

    Gdy najade kursorem na zmienna(plik_1), gdzie jest pełna nazwa pliku, to podświetla mi ładnie pełną nazwę pliku.

    Kod: vbscript
    Zaloguj się, aby zobaczyć kod


    clubs: niestety nie wiem jak sprawdzić co jest podane jako indeks Workbooks. W momencie, gdy makro jest uruchomione i dochodzi do tego momentu, gdzie występuje błąd, to otwarty jest plik, gdzie jest makro oraz nowo zapisany plik, który chce wyłączuć.
  • Poziom 29  
    Marco228 napisał:
    ... Makro ma za zadanie:
    1. otwarcie pliku "matki" do którego kopiuje pewne dane,
    2. następnie zapisuje go pod odpowiednia nazwą w odpowiedniej lokalizacji.
    3. ...po uruchomieniu makra takich operacji ma do wykonania kilkadziesiąt ...
    4. ... cały czas zostaja mi otwarte nowo utworzone pliki, które zapisało.


    Ad 1. Skąd te "pewne dane" są kopiowane do pliku "matki" ?
    A) Z wcześniej otwartego jakiegoś, pojedynczego zeszytu
    B) Z otwieranych po kolei jakichś plików (z jakiegoś katalogu), które następnie trzeba zamknąć ?

    Ad 2. Skąd biorą się te "odpowiednie": "nazwa" i "lokalizacja" ?

    Ad 3. Pytanie jak w pkt 1A) i 1B)
    Ad 4. W jaki sposób są one tworzone (odkopiowanie arkuszy, utworzenie nowych, itp.) oraz skąd brane jest info o lokalizacji zapisu ?

    Marco228 napisał:
    ... wcześniej w makrze otwieram jeszcze jeden plik z którego są kopiowane niektóre dane do pliku matki i bez problemu go zamykam

    :?:
    Wydzielasz innym te informacje na raty ... zacznij w takim razie od końca, gdzie najwięcej ich się zgromadziło ... :) ... bo może działa to na zasadzie łączenia kolejno następujących po sobie ... :) ...
    A najlepiej opisz jeszcze raz wszystko od początku ... w punktach.
  • Poziom 34  
    Marco228 napisał:
    Gdy najade kursorem na zmienna(plik_1), gdzie jest pełna nazwa pliku, to podświetla mi ładnie pełną nazwę pliku.
    Kod: vbscript Rozwiń Zaznacz wszystko
    Sub test_kopiowanie()
    Dim plik_1 As Variant
    plik_1 = Workbooks("glowny_plik.xls").Sheets("dane").Range("W2")
    Workbooks(plik_1).Sheets("kckw").Range("A1").Copy
    End Sub

    Sprawdź czy na pewno nazwa z 'Range("W2")' odpowiada temu otwartemu plikowi (może być jakaś spacja) i czy ten otwarty plik ma ten arkusz "kckw"
    Zobacz na której linij się 'wysypie'
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
  • Poziom 22  
    Czyli nadal nic nie wiemy. Zamień tę linijkę kodu (albo wstaw przed nią):
    Workbooks(plik_1).Sheets("kckw").Range("A1").Copy
    na:
    Workbooks(plik_1).Activate
    Sheets("kckw").Select
    Range("A1").Select
    i zobacz debuggerem gdzie się wywali. Następnie badaj dlaczego się wywaliło. A nie masz tam czegoś po tym Copy, np Destination:=... :-)
  • Poziom 16  
    Marco228 napisał:
    Makro ma za zadanie otwarcie pliku "matki" do którego kopiuje pewne dane, następnie zapisuje go pod odpowiednia nazwą w odpowiedniej lokalizacji.

    Czy nie lepiej zapisać nowy plik bez wielokrotnego otwierania pliku matki?
  • Poziom 4  
    clubs: tak na pewno jest to dobra ścieżka

    wysypało się na:

    plik_1 = Workbooks("glowny_plik.xls").Sheets("dane").Range("W2")

    pisze, ż eplik = empty


    lanzul: masz rację, może przybliże trochę działanie maka, myślałem, ze nie będzi eto konieczne, ale jednak. Trochę pewnie teraz namieszam, bo pokaże całe główne makro, wiem, że nie jest idealnie napisane i pewnie wiele rzeczy mozna zrobic lepiej, ale ucze się i to jest pierwsza wersja, która mimo wszystko działa bardzo dobrze oprócz tego, że nie wyłącza mi utworzonych plików i jeśli makro w automacie wykonuje powyżej 4 detali excel sie zawiesza(próbowałem puscić makro ręcznie przez uzywanie f8 i wykonało wszystko ładnie):

    1.W pliku głównym jest tabela, gdzie wpisuję dane odnośnie produkcji detali. Są tam takie informacje jak nazwa detalu, data rozpoczęnia produkcji, zmiana rozpoczęcia produkcji, data zakończenia produkcji, zmiana zakończenia produkcji oraz numer własny detalu.

    2. W jednym z folderów są pliki przypisane do każdego detalu (zmienna: Workbooks("" & numer & ".xls")) . Jeden plik na jeden detal, każdy z tych plików ma nazwę taką sama jak numer detalu, które wykorzystuje do pobrania z nich danych. Jedna z danych to informacja ile operacji ma być wykonanych dla danego detalu. Czasami jest tak, że dany detal musi zapisac 4 razy pod rózna nazwą (np. data produkcji poczatek i zmiana poczatek lub data produkcji koniec i data koniec) rodzaj danej operacji opisany jest na końcu oznaczeniem K1,P1, K1_1,P1_1 itp itd.

    3. Każdy detal swój osobny folder pod nazwą składającą się z numeru i nazwy detalu, gdzie zapisywany jest na końcu plik po wykonaniu wszystkich operacji.

    4. Makro na samym początku sprawdza czy dany detal o dacie i zmianie w tabeli nie był już wcześniej utworzony (szuka duplikatów) oraz czy kazdy detal z listy ma swój plik z (punktu nr 2). Zaznaczam, że to wszystko działa bardzo dobrze !

    5. Następnie makro ma za zadanie po kolei według listy detali wykonywac następujące czynności:
    - otwiera plik danego detalu (z punktu nr 2)
    -otwiera plik matka puste_kckw (czyli taki plik, który jest pustą formatką, w której zapisywane sa dane z pliku z punktu nr 2)
    - kopiuje dane z pliku z punktu nr 2 do pliku matka puste_kckw
    - wyłącza uruchomiony na początku plik z punktu nr 2
    - zapisuje plik matka puste_kckw pod nazwą skłądająca się ze zmiennych (data produkcji, zmiana, numer detalu i (oznaczenie końcowe zależne od rodzaju detalu).

    Po zapisie chciałbym wyłączyć własne ten plik i nie mogę...


    Kod: vbscript
    Zaloguj się, aby zobaczyć kod



    Mam nadzieję, że przybliżenie całego makra pokaże, gdzie popełniłem błędy.

    Dodano po 6 [minuty]:

    kinggustav napisał:
    Czyli nadal nic nie wiemy. Zamień tę linijkę kodu (albo wstaw przed nią):
    Workbooks(plik_1).Sheets("kckw").Range("A1").Copy
    na:
    Workbooks(plik_1).Activate
    Sheets("kckw").Select
    Range("A1").Select
    i zobacz debuggerem gdzie się wywali. Następnie badaj dlaczego się wywaliło. A nie masz tam czegoś po tym Copy, np Destination:=... :-)


    Próbowałem, ale nic nie daje nie ma żadnego Destination...
  • Pomocny post
    Poziom 34  
    Pytanie kolego odnajdujesz się w tym kodzie? :)
    Błąd masz w
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod


    acsz napisał:
    clubs: tak na pewno jest to dobra ścieżka

    a dokładnie (a pytałem o te spacje :) )
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
  • Poziom 4  
    clubs: DZIĘKI bardzo, jedna spacja, a tyle problemów :)
    Wszystko ładnie się wyłącza po każdej operacji. Brawo za spostrzegawczość ! :)

    Co do pytania czy odnajduje sie w kodzie, to w końcu sam go napisałem i dla mnie jest czytelny, choć wygląda na zagmatwany przez ilośc zmiennych i funkcji if, to spełnia swoja rolę idealnie.

    Panowie wyskoczył mi inny problem, który myślałem, że rozwiąże przy okazji poprzedniego.
    Program działa bez zarzutu, tak jak pisałem wcześniej raz nawet przejechałem ręcznie przy użyciu f8 i makro wykonało bez problemu wszystkie niezbędne operacje na ponad 10 detalach.
    Problem pojawia sie przy puszczeniu go w automacie. Jeśli w liście mam więcej niż 4 detale program się wykrzacza i zawiesza excel.
    Oto co pisze w wyskakującym okienku... ( po naciśnieciu czegokolwiek excel się wyłącza całkowicie)


    Kod: tex
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    Poziom 29  
    Marco228 napisał:
    ... Co do pytania czy odnajduje sie w kodzie, to w końcu sam go napisałem i dla mnie jest czytelny, choć wygląda na zagmatwany przez ilośc zmiennych i funkcji if, to spełnia swoja rolę idealnie ...
    ... Program działa bez zarzutu, tak jak pisałem wcześniej ...
    Wybacz mój "sceptycyzm", ale wątpię.

    W kodzie, który zamieściłeś (Sub KCKW):
    1. Brak jest deklaracji wielu zmiennych, np.: k3, k5, k6, k8, k9, k10, k13, k14, k17, k23, w1, data_poczatek, zmiana_poczatek, sciezka
    2. Gdzie w tym kodzie, prócz deklaracji i przypisania wartości, występuje zmienna "K As Integer" ?
    3. Dlaczego "Application.ScreenUpdating = False" umieścileś w pętli, a nie na początku makra ?
    4. Dlaczego "Application.DisplayAlerts = False" nie ma odwołania (czyli ustawienia na True) po otwarciu pliku ? Jeśli chodziło ci tylko o wyłączenie komunikatów na otwarcie pliku, to po jego otwarciu trzeba je włączyć aby wiedzieć czy coś "nie tego", inaczej po co wielokrotnie wyłączać w pętli, to co już raz zostało wyłączone ? To już lepiej wyrzucić to poza pętlę.
    5. Nie wszędzie po kopiowaniu masz "Application.CutCopyMode = False", "czyszczące pamięć"
    6. W wielu miejscach makra masz sekcje wylistowujące jakieś wartości przy pomcy "If" i na ich podstawie powielające pewne bloki kodu:
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
    , gdzie x = 1, 2, 3, 4 itd.
    Zamiast tego zastosuj konstrukcję "Select Case x", jest "szansa", że dość pokaźnie skrócisz swój kod
    7. Zamiast wielokrotnie powtarzać konstrukcje typu "Workbooks("Master do kckw.xls").Sheets("dane")" zastosuj:
    a) przypisania obiektowe Set, tj.
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
    i odwołuj się potem do obiektów poprzez ich nazwę symboliczną.
    lub
    b) konstrukcje z "With ... End With"
    skrócą ci one kod.

    8. Jeśli otwarłeś jakiś plik ("Zeszyt1.xls"), wykonałeś na nim jakieś operacje i jest on cały czas w "pierwszoplanowej roli" (nie przesłonięty całą masą innych obiektów) i chcesz go zamknąć i zapisać pod inną nazwą, to po prostu wykonaj:
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
    zamiast go zostawiać w całej masie innych plików i zastanawiać się potem jak go zamknąć

    9. Na samym początku pętli "For...Next" masz linię:
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
    , która, sądząc po wcześniejszych linijkach, jest odniesieniem do "Master do kckw.xls"

    Dlaczego zostawiasz ją w pętli bez "Workbooks("Master do kckw.xls")." ?
    Czy jesteś na 100% pewien, że przy otwieraniu innych zeszytów, w których masz ewentualnie arkusze o takich samych nazwach ("dane"), odpowiednie wartości zostaną pobrane z właściwych zakładek właściwego pliku ?
    Pamiętaj, że zapis "Sheets("dane")." odnosi się do arkusza "dane" w aktywnym zeszycie, a z tym różnie może być, jak nie dopilnujesz kodu
  • Poziom 4  
    lanzul:

    Dzięki za tak obszerna odpoweidź, już staram sie odpowiedziec na Twoje pytania:
    1. Tak masz rację nie zadeklarowałem zmiennych, po prostu zapomniałem tego dopisać jak makro działało i potem o tym nie myślałem.
    2. zmienna K to pozostałośc po mojej początkowej fazie pisania tego kodu i nie usunąłem tego.
    3. Ponieważ, gdy umieszczam ja tylko na początku makra i tak odświeża , więc dołozyłem jeszcze w kilka miejsc i działa.
    4. Ponieważ otwierane pliki maja jakieś makra, które po otwarciu uruchamiają okienka informacyne, a tego nie chce.
    5. Do poprawienia
    6. Dzięki za informacje, uczę się dopiero i nie znam wszystkich możliwości. Spróbuje wykorzystac tą metodę.
    7. Tak jak powyżej w pkt. 6.
    8. Tak jak w pkt 6. Nie wiedziałem, że tak można :)
    9. Faktycznie spory błąd mógł się zemścic w przyszłości, już poprawiłem.

    Poza tym wierz lub nie, ale makro działa. O dziwo bardzo dobrze, bo wykonałem już kilka możliwych scenariuszy i idzie. Możliwe, że wyjdzie jeszcze coś w przyszłości, wtedy sie odezwę.

    Będę teraz próbował ulepszyć makro o Twoje uwagi i wyczyścić z niepotrzebnych rzeczy.

    Co do mojego ostatniego postu o tym, że makro zawiesza excela jeśli są więcej niż 4 detale, to na innym komputerze działa bez zarzutu . Nie wiem czym jest to spowodowane.
  • Poziom 29  
    Marco228 napisał:
    3. Ponieważ, gdy umieszczam ja tylko na początku makra i tak odświeża , więc dołozyłem jeszcze w kilka miejsc i działa.
    4. Ponieważ otwierane pliki maja jakieś makra, które po otwarciu uruchamiają okienka informacyne, a tego nie chce.

    Chodziło mi o takie konstrukcje "DisplayAlerts" i "ScreenUpdating":
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod

    względnie takie:
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod
  • Poziom 34  
    Marco228 napisał:
    Panowie wyskoczył mi inny problem, który myślałem, że rozwiąże przy okazji poprzedniego.
    Program działa bez zarzutu, tak jak pisałem wcześniej raz nawet przejechałem ręcznie przy użyciu f8 i makro wykonało bez problemu wszystkie niezbędne operacje na ponad 10 detalach.
    Problem pojawia sie przy puszczeniu go w automacie. Jeśli w liście mam więcej niż 4 detale program się wykrzacza i zawiesza excel.
    Oto co pisze w wyskakującym okienku... ( po naciśnieciu czegokolwiek excel się wyłącza całkowicie)

    Zobacz tak
    1 Otwórz 'vba' w module w którym masz kod na samej górze wpisz jakiś komentarz (wyłączony) np
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod

    2 w menu - Debug menu - kliknij Compile VBA Project
    3 powtórz dla każdego module gdzie masz kod
    4 zamknij skoroszyt i zapisz zmiany
  • Poziom 29  
    Poza tym naprawdę powinieneś jeszcze raz przejrzeć kod i zastanowić się nad nim, przykładowo fragment:
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod

    Zacznijmy ...
    1. Wykonanie kodu dochodzi do pętli głównej "For...Next"
    2. W pętli następuje przypisanie jakiejś wartości do "numer"
    3. Jakieś polecenia
    4. Następuje otwarcie pliku o nazwie "numer.xls"
    5. Jakieś polecenia
    6. Jeśli zmienna = 1 to następuje zamknięce pliku "numer.xls"
    7. ... ale ... Jeśli zmienna <> 1 (np. zmienna = 2) to zamknięce pliku "numer.xls" nie nastąpi
    8. ... następnie ... Jeśli zmienna = 2 to ...
    9. Zmieniasz wartość zmiennej "zmienna2" na "1"
    10. by następnie w kolejnej pętli "For...Next"
    11. przypisać jej wartość początkową ponownie "1", jak powyżej ... po co ?
    12. po czym otwierasz plik "numer.xls" ... być może otwarty już wcześniej ...
    13. Jakieś polecenia
    14. Zamknięcie pliku "numer.xls" ... bez zapisu ...
    15. i teraz ... wahadło ... jojo ... naprzemiennie ... raz "1", raz "2"

    Tutaj pętla chyba w ogóle nie byłaby potrzebna ... a te zmienna2 = 1 / = 2, to można zapisać przecież:
    Kod: vbscript
    Zaloguj się, aby zobaczyć kod

    Bardzo to sobie wszystko pokomplikowałeś.