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

Makro w programie Excel, jak wykonać?

gcz4 28 Mar 2011 21:37 5816 17
  • #1 28 Mar 2011 21:37
    gcz4
    Poziom 10  

    Witam serdecznie
    Na początku zaznaczam, że jestem na początku swojej drogi z "zabawą" makrami w Ecxcel'u.
    Potrzebuje napisać makro, które pobierze mi tekst z komórki np. B3 z pliku 1.xlsm i utworzy nowy plik excel o nazwie komórki B3. Następnie do tego nowego pliku skopiuje dane z arkusza "xyz" pliku 1.xlsm zachowując przy tym formatowanie komórek arkusza xyz (są różne szerokości i wysokości komórek). Próbowałem rozwiązać to zadanie za pomocą nagrywania makra ale niestety jak do tej pory nie podołałem temu zadaniu
    Bardzo proszę o pomoc.

    0 17
  • Pomocny post
    #2 28 Mar 2011 22:25
    adamas_nt
    Moderator Programowanie

    Po pierwsze: z którym fragmentem nagranego kodu masz problem?
    Po drugie: Nagraj makro kopiowania całego arkusza do nowego pliku ze zmianą jego (pliku) nazwy. Masz 100% gwarancji zachowania formatowania. Jeśli w arkuszu jest nadmiar danych można dopisać usuwanie.

    Jeśli jesteś początkujący, to nagrywarka jest podstawą. Przykład:
    To jest nagrane makro wg w/w opisu (Excel 2007)

    Kod: vb
    Zaloguj się, aby zobaczyć kod

    I uzupełnione w pobieranie nazwy z B3 arkusza 1
    Kod: vb
    Zaloguj się, aby zobaczyć kod

    0
  • #3 29 Mar 2011 09:12
    gcz4
    Poziom 10  

    Bardzo dziękuję za pomoc.
    Mam tylko jeszcze jedno pytanie. Co zrobić żeby w przypadku gdy plik o danej nazwie już istnieje i chcę zrezygnować z zapisu pliku nie wyskakiwał mi błąd:
    Run-time error '1004'
    Method 'SaveAs' of object'_Workbook' failed

    I jeszcze jedna sprawa:
    Załóżmy, że w kopiowanym arkuszu "xyz" są puste komórki np:A2, C3, D5.
    Jak zrobić żeby automatycznie do tych pustych komórek wpisywany był znak "-"

    0
  • Pomocny post
    #4 29 Mar 2011 15:54
    adamas_nt
    Moderator Programowanie

    1. Najprościej wyłączyć obsługę błędów

    Kod: vb
    Zaloguj się, aby zobaczyć kod


    2. Tu trzeba sprawdzić wartość i warunkowo przypisać inną. Najprościej
    Kod: vb
    Zaloguj się, aby zobaczyć kod
    i tak dla każdej komórki. Pół biedy jeśli jest ich kilka, ale jeżeli mamy ich kilkanaście lub więcej, wtedy wygodniej jest zastosować pętlę For Each element in kolekcja. Np
    Kod: vb
    Zaloguj się, aby zobaczyć kod

    0
  • Pomocny post
    #5 29 Mar 2011 17:54
    Aldrin
    Poziom 22  

    gcz4 napisał:
    Co zrobić żeby w przypadku gdy plik o danej nazwie już istnieje

    Jestem za tym, żeby sprawdzić obecność takiego pliku przez:

    If Dir(Thisworkbook.path & "\" & nazwa)<>"" then ...

    i podjąć dalsze działania (zapisać plik, podać komunikat, itp.)

    0
  • #6 30 Mar 2011 11:01
    gcz4
    Poziom 10  

    Z góry przepraszam za pewnie dla większości banalne pytania ale nie mogę sobie z tym poradzić.
    1.Jak zmodyfikować powyższe makro aby z arkusza z plik o nazwie 1 do nowego pliku o nazwie komórki B3 z pliku 1 kopiowały się dwa arkusze ("xyz" i "abc") z czterech jakie posiada plik 1.
    2. Co zrobić aby ten nowy plik o nazwie wziętej z komórki B3 pliku 1 zapisywał się jako plik z obsługą makr.
    3. W pliku 1 jest "Przycisk" pod którym jest ukryte makro zapisujące nowy plik o nazwie komórki B3 we wskazanej lokalizacji(np. na pulpicie w Katalogu AA). Czy da się tak zrobić aby "Przycisk" był "zablokowany (nie można go użyć - wcisnąć) w momencie gdy w katalogu AA jest już plik o nazwie komórki B3 z pliku 1.
    Mam nadzieję, że za bardzo nie zagmatwałem.
    Próbowałem nagrywać makra ale na razie niewiele z tego wychodzi. Nie poddaję się jednak i będę próbował dalej.
    Jeśli ktoś zna jakąś dobrą stronę internetową lub książkę z podstawami VBA w ecxelu (w szczególności z zakresu nagrywania makr) to bardzo proszę o info.

    0
  • Pomocny post
    #7 30 Mar 2011 14:58
    adamas_nt
    Moderator Programowanie

    Ad 1) Czy plik, który nazywasz "plik 1" jest tym, z którego uruchamiasz makro? Jeśli tak, to dopisz

    Kod: vb
    Zaloguj się, aby zobaczyć kod

    Ad 2) Kiepsko korzystasz z nagrywarki :) Jeżeli nagrasz makro zapisywania pliku z obsługą makr (właśnie to zrobiłem), to zauważysz że różnica jest tylko w rozszerzeniu (xlsm) i formacie (FileFormat:=xlOpenXMLWorkbookMacroEnabled)

    Ad 3) Tak. Sposobem, na który zwrócił uwagę kolega Aldrin. Makro powinno znajdować się (moim zdaniem) przy zdarzeniach: Thisworkbook_Open (aby sprawdzić przy starcie) oraz Worksheet_Change, gdzie Target.Address=B3). W tym przypadku ustawiasz właściwość Enabled przycisku (wartość True lub False).
    Przykład w załączniku

    0
  • #8 30 Mar 2011 18:41
    gcz4
    Poziom 10  

    adamas_nt napisał:

    Ad 2) Kiepsko korzystasz z nagrywarki :)

    Wiem:( ale tak jak wspomniałem jestem początkujący w tej dziedzinie.
    Bardzo dziękuję za pomoc i przykład. Właśnie o coś takiego mi chodziło.
    :)

    0
  • #9 01 Kwi 2011 14:52
    gcz4
    Poziom 10  

    Witam,
    No to jeszcze jedno pytanko. W moim pliku "1" dołożyłem drugi przycisk "CommandButton1", który zapisuje mi dane i zamyka skoroszyt. Chciałbym zrobić tak, że gdy "aktywny" jest pierwszy przycisk to ten mój (do zapisywania) jest nieaktywny. I na odwrót.
    Jak to zrobić??

    0
  • Pomocny post
    #10 01 Kwi 2011 16:42
    adamas_nt
    Moderator Programowanie

    We wszystkich makrach wartość Enabled przycisku 2 ustaw odwrotnie niż przycisku 1. Np

    Kod: vb
    Zaloguj się, aby zobaczyć kod

    0
  • #11 01 Kwi 2011 17:24
    gcz4
    Poziom 10  

    adamas_nt napisał:
    We wszystkich makrach wartość Enabled przycisku 2 ustaw odwrotnie niż przycisku 1. Np
    Kod: vb
    Zaloguj się, aby zobaczyć kod

    Rzeczywiście pomogło wielkie dzięki.
    Teraz makro działa w ten sposób, że:
    Włączam plik "1">> wciskam "cmdsave">> program kopiuje mi wszystko to co chcę>> dezaktywuje się plik "cmdsave" ale niestety nie aktywuje się automatycznie "cmdexit" :(. zmienia się to dopiero wtedy gdy zamknę i ponownie uruchomię plik "1". Co jest nie tak ??

    0
  • #12 01 Kwi 2011 21:46
    adamas_nt
    Moderator Programowanie

    We wszystkich makrach, w kodzie arkusza także. Fragmenty z załącznika:
    W kodzie przycisku zapisz

    Kod: vb
    Zaloguj się, aby zobaczyć kod
    W kodzie arkusza przy zmianie:
    Kod: vb
    Zaloguj się, aby zobaczyć kod

    0
  • #13 04 Kwi 2011 09:37
    gcz4
    Poziom 10  

    Bardzo dziękuję za dotychczasowe podpowiedzi i wskazówki.
    Potrzebuję napisać jeszcze jedno makro.
    Makro ma wyszukać plik o nazwie komórki "B3" pliku 1 znajdujący się na dysku "C:\" i jeśli jest ten plik to otworzyć go a jeśli nie ma to wyświetlić komunikat "Brak pliku".
    Z góry dziękuję za pomoc

    0
  • #14 04 Kwi 2011 14:54
    adamas_nt
    Moderator Programowanie

    Makro masz już gotowe

    Code:
    If Dir(ThisWorkbook.Path & "\" & nazwa) = Empty Then
    należy pozmieniać tylko polecenia. Jeśli Empty, to znaczy że nie ma i wyświetlasz komunikat, w przeciwnym wypadku otwierasz. Poczytaj o metodzie Workbooks.Open i argument posklejaj ze zmiennych (patrz kod wyżej).

    0
  • #15 04 Kwi 2011 19:44
    gcz4
    Poziom 10  

    Moje makro wygląda tak

    Cytat:

    Private Sub CommandButton1_Click()
    If Dir("C:\Documents and Settings\xxx\Pulpit\Nowy folder" & "\" & nazwa) = Empty Then

    MsgBox ("Brak pliku")
    Else
    Workbooks.Open Filename:= _
    "C:\Documents and Settings\xxx\Pulpit\Nowy folder" & " \ " & nazwa

    End If
    End Sub

    Niestety po uruchomieniu makra wyskakuje błąd run-time error '1004' i komunikat że nie można odnaleźć pliku.
    Makro działa poprawnie jeśli w miejsce
    Cytat:

    Workbooks.Open Filename:= _
    "C:\Documents and Settings\xxx\Pulpit\Nowy folder" & " \ " & nazwa

    zamiast & " \ " & nazwa wpiszę konkretną nazwę pliku.
    Co robię nie tak??

    0
  • #16 04 Kwi 2011 20:56
    adamas_nt
    Moderator Programowanie

    Zmienna "nazwa" nie ma wartości... Umieść przypisanie przed ifem

    Code:
    nazwa = Sheets(1).Range("B3") & ".xlsm"
    Cały string możesz uprościć do postaci
    Code:
    "C:\Documents and Settings\xxx\Pulpit\Nowy folder\" & nazwa

    0
  • #17 05 Kwi 2011 08:28
    gcz4
    Poziom 10  

    Dziękuję bardzo w końcu po wielu próbach zadziałało :-).
    W ramach nauki VBA chciałbym trochę udoskonalić powyższe makra.
    Obecnie w pliku 1 mam dwa przyciski cmdSave i CommandButton1, które działają w następujący sposób:
    cmdSave -tworzy mi plik o nazwie komórki B3 pliku 1 i zapisuje na dysku we wskazanej lokalizacji (jest aktywny przy otwarciu pliku 1 gdy pliku o nazwie B3 nie ma, w przeciwnym wypadku jest nieaktywny)
    CommandButton1 - otwiera mi plik o nazwie komórki B3 pliku 1 (jeśli ten plik jest utworzony- przycisk jest aktywny; w przeciwnym wypadku jest nieaktywny)
    Załóżmy że chciałbym stworzyć jeszcze jeszcze trzy pary przycisków tak aby:
    pierwsza para
    przycisk "a" działał tak jak cmdSave tylko tworzył plik o nazwie komórki B4
    przycisk "b" działał tak jak CommandButton1 tylko otwierał plik o nazwie B4 (jeśli jest)
    druga para
    przycisk "c" działał tak jak cmdSave tylko tworzył plik o nazwie komórki B5
    przycisk "d" działał tak jak CommandButton1 tylko otwierał plik o nazwie B5 (jeśli jest)
    trzecia para
    przycisk "e" działał tak jak cmdSave tylko tworzył plik o nazwie komórki B6
    przycisk "f" działał tak jak CommandButton1 tylko otwierał plik o nazwie B6 (jeśli jest).
    Każda para ma działać jak dwa wzorcowe przyciski: jeśli jeden jest aktywny to drugi nie.
    Czy da się jakoś 'zautomatyzować to makro'?
    Oczywiście mogę utworzyć sześc kolejnych przycisków i skopiować do nich odpowiednie formuły zmieniając tylko nazwę komórki na B4, B5,B6.
    W przypadku małej ilości przycisków można się tak bawić a co jeśli tych par będę chciał mieć np 100?

    0
  • #18 05 Kwi 2011 17:01
    Aldrin
    Poziom 22  

    gcz4 napisał:
    Każda para ma działać jak dwa wzorcowe przyciski: jeśli jeden jest aktywny to drugi nie.
    Oczywiście mogę utworzyć sześc kolejnych przycisków...
    a co jeśli tych par będę chciał mieć np 100?

    To trzeba przemysleć na etapie budowania arkusza. Jeśli miały być dwa przyciski, to są dwa przyciski. Wcale tak jednak być nie musi. Można osadzić w arkuszu JEDEN przycisk, który w zależności od spełnionego warunku (IF) będzie wykonywać czynność pierwszą albo drugą. Dodatkowo, żeby nie było wątpliwości w jakim jest aktualnie stanie, można dołączyć zmianę .Caption w kodzie przycisku, czyli wpisać np.:
    cmdPrzycisk.Caption = "otwórz plik" lub
    cmdPrzycisk.Caption = "zapisz plik".

    Takie działanie zredukuje ilość przycisków o połowę. Nie trzeba się zastanawiać co klikać w danym momencie i celować w dany przycisk ;)

    Jeśli przycisków ma być duużo więcej, to warto rozważyć zupełnie inne rozwiązanie, np. wybór danego wariantu z Option List. Tu jednak dużo zależy od przeznaczenia arkusza, bo jeśli miałbym każdego dnia 200 razy wybierać coś z listy i za każdym razem wyszukiwać odpowiedni element, to wolałbym kliknąc po prostu w odpowiedni przycisk.

    0