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.

Makro w programie Excel, jak wykonać?

28 Mar 2011 21:37 5987 17
  • 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.
    Darmowe szkolenie: Ethernet w przemyśle dziś i jutro. Zarejestruj się za darmo.
  • Pomocny post
    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
  • 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 "-"
  • Pomocny post
    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
  • Pomocny post
    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.)
  • 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.
  • Pomocny post
    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
  • 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.
    :)
  • 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ć??
  • Pomocny post
    Moderator Programowanie
    We wszystkich makrach wartość Enabled przycisku 2 ustaw odwrotnie niż przycisku 1. Np
    Kod: vb
    Zaloguj się, aby zobaczyć kod
  • 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 ??
  • 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
  • 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
  • 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).
  • 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??
  • 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
  • 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?
  • 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.