Jak zrobić makro, które tworzy nowy skoroszyt na podstawie szablonu

0
8
Rate this post

Nawigacja:

Po co tworzyć nowy skoroszyt z szablonu – scenariusze z życia biurowego

Kiedy makro z szablonem naprawdę się przydaje

Makro, które tworzy nowy skoroszyt na podstawie szablonu, ma sens wszędzie tam, gdzie robisz w kółko to samo. Zwykle chodzi o raporty cykliczne, powtarzalne zestawienia lub standardowe formularze wypełniane przez wiele osób. Typowe przykłady:

  • codzienne raporty sprzedaży lub produkcji,
  • miesięczne zestawienia kosztów, budżetów, godzin pracy,
  • arkusze zamówień dla klientów lub działów,
  • standardowe formularze reklamacyjne, wnioski urlopowe, protokoły odbioru,
  • karty projektów, które zawsze wyglądają tak samo.

W każdym z tych przypadków struktura skoroszytu jest niezmienna: te same arkusze, formaty, formuły, czasem także makra. Zmieniają się tylko dane i ewentualnie nazwa pliku. Automatyzacja sprowadza się więc do jednego: szybkiego utworzenia nowego pliku na podstawie stałego wzorca.

Różnica między „pustym plikiem” a skoroszytem z szablonu

Zwykły, pusty skoroszyt Excela to zestaw domyślnych ustawień: kilka arkuszy, brak formatowania, brak formuł, żadnych nazw zakresów, brak ochrony. Każde wymagane ustawienie trzeba zbudować ręcznie albo skopiować z innego pliku. Przy jednorazowej akcji to żadna tragedia, ale przy pracy codziennej czas i błędy rosną wykładniczo.

Skoroszyt tworzony z szablonu ma od razu:

  • odpowiednią liczbę i nazwy arkuszy,
  • ustawione formatowanie, style, kolory,
  • gotowe formuły, tabele przestawne, wykresy,
  • zdefiniowane nazwy zakresów,
  • ustawione zabezpieczenia (zablokowane komórki, ukryte formuły, hasło do arkusza),
  • ewentualne makra, zdarzenia, przyciski.

Efekt jest taki, że użytkownik od razu wpisuje dane, zamiast zastanawiać się „czy dobrze skopiowałem szablon” i „czy wszystkie formuły się zgadzają”. Nowy skoroszyt jest już technicznie poprawny, a makro tylko pomaga go szybko utworzyć i zapisać.

Oszczędność czasu i redukcja błędów

Ręczne kopiowanie pliku „wzorcowego” ma kilka wad: użytkownik może skasować lub nadpisać oryginał, pomylić foldery, niechcący zmienić struktury arkusza lub formuły, zanim zapisze nową kopię. Przy kilku osobach w dziale robi się z tego loteria.

Makro tworzące nowy skoroszyt na podstawie szablonu pozwala:

  • ustandaryzować proces tworzenia plików,
  • wyeliminować ryzyko modyfikacji oryginalnego szablonu,
  • narzucić docelowy folder zapisu (np. wspólny katalog raportów),
  • automatycznie generować spójne nazwy plików (z datą, numerem, inicjałami),
  • dołożyć kontrolę błędów – np. nie utworzy raportu, jeśli szablon został przeniesiony lub usunięty.

Niewielka inwestycja w kod VBA często zwraca się w pierwszych tygodniach używania, szczególnie w większych zespołach, gdzie pliki krążą między wieloma użytkownikami.

Dlaczego makro, a nie ręczne wybieranie szablonu

Excel oczywiście pozwala utworzyć plik na podstawie szablonu z poziomu interfejsu: przycisk „Nowy”, wybór kategorii, wskazanie szablonu. Problem w tym, że:

  • użytkownicy lubią iść na skróty i otwierają „jakiś stary plik, bo jest podobny”,
  • nie każdy pamięta, gdzie szablony są zapisane, szczególnie gdy leżą na zasobie sieciowym,
  • trzeba klikać więcej kroków, co kusi do „tymczasowych obejść”, które potem stają się standardem.

Makro można podpiąć pod przycisk na wstążce, ikonkę na pasku szybkiego dostępu albo skrót klawiaturowy. Jedno kliknięcie lub kombinacja klawiszy i gotowe – nowy raport lub formularz otwiera się w ustandaryzowanej postaci. Dla użytkownika to prostsze, dla administratora szablonu – bezpieczniejsze.

Krótki przykład z życia

Wyobraź sobie, że codziennie o 8:00 generujesz raport sprzedaży. Twój rytuał: otworzyć wczorajszy plik, zapisać jako nowy, zmienić datę, wyczyścić dane, poprawić formułę, która „znów się nie skopiowała do końca”. Trwa to kilka minut i zawsze może coś pójść nie tak.

Po wprowadzeniu makra sekwencja wygląda inaczej: wciskasz skrót klawiszowy, Excel tworzy nowy skoroszyt z szablonu raportu, nadaje nazwę „Raport_sprzedazy_2024-04-21.xlsx”, zapisuje go w katalogu „SerwerRaportySprzedaz2024”, a ty od razu wklejasz dane z systemu. Cały „nudny” etap przygotowania pliku znika.

Zespół programistów pracuje przy komputerach w nowoczesnym biurze tech
Źródło: Pexels | Autor: cottonbro studio

Podstawy: czym jest szablon Excela i jak go przygotować

Różnice między zwykłym plikiem a szablonem

Excel rozróżnia standardowe pliki i szablony przede wszystkim po rozszerzeniu:

Typ plikuRozszerzenieZ makrami?Zastosowanie
Zwykły skoroszyt.xlsxNieDane, raporty bez VBA
Skoroszyt z makrami.xlsmTakPliki z kodem VBA
Szablon bez makr.xltxNieWzorce raportów, formularzy
Szablon z makrami.xltmTakSzablony z logiką VBA

Technicznie szablon to plik, który Excel traktuje jako wzorzec do tworzenia nowych skoroszytów. Użytkownik nie powinien bezpośrednio w nim pracować, tylko tworzyć na jego podstawie nowe pliki. Dzięki temu szablon zachowuje swoją „czystość”: układ, formuły i zabezpieczenia pozostają nienaruszone.

Jak zaprojektować i zapisać szablon Excela

Dobry szablon to połowa sukcesu całego rozwiązania. Samo makro tylko go uruchamia, więc im lepiej dopracowany wzorzec, tym mniej komplikacji później. Przy projektowaniu szablonu opłaca się przejść przez checklistę:

  • utworzyć wymagane arkusze, nadać im jasne nazwy,
  • ustawić formatowanie (nagłówki, kolory, style liczb),
  • dodać wszystkie niezbędne formuły i przetestować je na danych przykładowych,
  • zdefiniować nazwy zakresów dla kluczowych obszarów (np. DaneWejsciowe, TabelaRaportu),
  • ukryć techniczne arkusze, jeśli nie są potrzebne użytkownikowi,
  • zablokować formuły, które nie powinny być modyfikowane.

Po przygotowaniu wzorca przy zapisie trzeba wybrać typ pliku Szablon programu Excel (*.xltx) albo Szablon programu Excel z makrami (*.xltm). To rozszerzenie ma znaczenie dla metody Workbooks.Add, która wykorzysta go później jako źródło nowego skoroszytu.

Gdzie zapisać szablon – lokalnie czy w sieci

Lokalizacja szablonu ma wpływ na wygodę użytkowników i konstrukcję makra. Zwykle stosuje się trzy warianty:

  • Folder domyślny szablonów użytkownika – Excel potrafi go używać w swoim oknie „Nowy”. To lokalne rozwiązanie, dobre dla pojedynczego użytkownika.
  • Folder wspólny na dysku sieciowym – rekomendowany scenariusz, gdy z szablonu korzysta cały zespół. Makro wskazuje ścieżkę typu serwerdzialSzablonyRaport.xltx.
  • OneDrive / SharePoint – w środowisku Microsoft 365 szablony często lądują w chmurze. Ścieżki są tu dłuższe i złożone, ale Excel i tak widzi je jako zwykłe ścieżki folderów.

W makrze można wykorzystać ścieżkę absolutną (zakodowaną na stałe) lub budować ją dynamicznie, np. opierając się na lokalizacji pliku z makrem (ThisWorkbook.Path). Druga opcja ułatwia przenoszenie rozwiązania między komputerami.

Kiedy użyć szablonu z makrami (.xltm), a kiedy wystarczy .xltx

Szablon z makrami (.xltm) jest potrzebny wtedy, gdy nowo tworzony skoroszyt ma mieć własny kod VBA: przyciski z logiką, zdarzenia arkuszy, funkcje użytkownika, procedury importu danych. Jeśli makro, którego celem jest tylko utworzenie nowego pliku, znajduje się w osobnym skoroszycie (np. „PanelRaportów.xlsm”), szablon może spokojnie być bez makr – zwykłe .xltx.

Bez makr w szablonie:

  • nie ma komunikatów o zabezpieczeniach VBA po otwarciu raportu,
  • łatwiej go użyć u osób, które mają zablokowane makra,
  • mniej problemów przy wysyłaniu mailem (systemy bezpieczeństwa mniej się go „czepiają”).

Szablon .xltm jest konieczny dopiero wtedy, gdy logika VBA musi być częścią każdego nowego pliku, np. przy złożonych formularzach, które walidują dane lub komunikują się z bazą.

Najczęstsze pułapki przy projektowaniu szablonu

Szablon może być piękny wizualnie, a i tak sprawiać problemy w codziennym użyciu. Typowe kłopoty, które potem „wychodzą” dopiero przy masowym tworzeniu plików:

  • scalone komórki w obszarach, gdzie użytkownik wpisuje dane – utrudniają filtrowanie, sortowanie, kopiowanie; makra też ich nie lubią,
  • zbyt agresywne blokowanie komórek – użytkownik nie może wpisać danych tam, gdzie powinien,
  • ukryte arkusze z danymi pomocniczymi, których ktoś kiedyś potrzebuje, ale nie wie o ich istnieniu,
  • formuły odwołujące się do konkretnych plików, zamiast działać w ramach bieżącego skoroszytu,
  • przekombinowane formatowanie warunkowe, które spowalnia pracę na słabszych komputerach.

Przed „oddaniem” szablonu użytkownikom warto przetestować go w typowym scenariuszu: wypełnić danymi, przefiltrować, wydrukować, zapisać pod inną nazwą. Lepiej wychwycić problemy na etapie wzorca niż potem w kilkudziesięciu wygenerowanych plikach.

Minimalne podstawy VBA potrzebne do makra uruchamiającego szablon

Struktura prostego makra w VBA

Do napisania makra tworzącego nowy skoroszyt z szablonu wystarczą podstawowe elementy VBA. Kluczowe pojęcia:

  • Moduł standardowy – miejsce, w którym zapisuje się „zwykłe” procedury, np. Sub UtworzRaport().
  • Procedura Sub – blok kodu wykonywany po wywołaniu, np. po kliknięciu przycisku.
  • Komentarze – linie zaczynające się od ', pozwalają opisać, co robi kod.

Najprostsza procedura wygląda tak:

Sub PrzykladoweMakro()
    ' To jest komentarz opisujący działanie makra
    MsgBox "Makro działa"
End Sub

Aby dodać moduł, w edytorze VBA (Alt+F11) używa się polecenia Insert > Module i wkleja kod do powstałego modułu. Tak samo zrobisz z makrem tworzącym skoroszyt na podstawie szablonu.

Różnica między ThisWorkbook, ActiveWorkbook i innymi skoroszytami

Podczas pracy z wieloma plikami w VBA ważne jest rozróżnienie, do którego skoroszytu się odwołujesz. Excel stosuje tu kilka kluczowych obiektów:

  • ThisWorkbook – skoroszyt, w którym znajduje się aktualnie wykonywany kod VBA. To zwykle „panel sterujący” z makrami.
  • ActiveWorkbook – aktualnie aktywny skoroszyt (ten, którego okno jest na wierzchu). Po utworzeniu nowego pliku to najczęściej właśnie on.
  • Workbooks(„Nazwa.xlsx”) – konkretny, nazwany skoroszyt otwarty w Excelu.

Przykład:

Praktyczne przykłady z ThisWorkbook i ActiveWorkbook

Najprościej zobaczyć różnicę na konkretnych wywołaniach. Załóżmy, że masz otwarty plik z makrami PanelRaportów.xlsm oraz zwykły skoroszyt z danymi DaneSprzedaz.xlsx. Makro jest zapisane w PanelRaportów.xlsm.

Sub PrzykladWorkbookow()

    ' Zawsze wskaże PanelRaportów.xlsm,
    ' bo tam siedzi ten kod
    Debug.Print "ThisWorkbook: " & ThisWorkbook.Name

    ' Zwróci ten skoroszyt, który jest aktualnie na wierzchu
    Debug.Print "ActiveWorkbook: " & ActiveWorkbook.Name

    ' Jawne wskazanie po nazwie
    Debug.Print Workbooks("DaneSprzedaz.xlsx").Name

End Sub

Jeżeli w trakcie działania makra utworzysz nowy skoroszyt, bardzo łatwo „zgubić” się w tym, który plik jest aktywny. Dlatego przy pracy z szablonami rozsądnie jest zapamiętać referencję do nowego skoroszytu w zmiennej obiektowej:

Dim wbNowy As Workbook
Set wbNowy = Workbooks.Add  ' tu za chwilę wejdzie nasz szablon

Od tego momentu wbNowy jednoznacznie wskazuje na tworzony plik, nawet jeśli użytkownik przypadkiem kliknie myszką w inne okno Excela.

Proste zmienne, które przydadzą się w makrze

W makrze uruchamiającym szablon używa się kilku typów zmiennych. Nie trzeba wchodzić w całą teorię typów, wystarczy „zestaw startowy”:

  • Dim sciezka As String – przechowa lokalizację szablonu lub folderu docelowego,
  • Dim nazwaPliku As String – nazwa tworzonego skoroszytu, zwykle z datą lub numerem,
  • Dim wbNowy As Workbook – referencja do nowo utworzonego pliku,
  • Dim dt As Date – data, którą można wstawić do nazwy lub do komórek w raporcie.

Prosty „szkielet” makra, który tę logikę zbiera w całość, wygląda tak:

Sub UtworzNowyRaport()

    Dim sciezkaSzablonu As String
    Dim sciezkaDocelowa As String
    Dim nazwaPliku As String
    Dim wbNowy As Workbook
    Dim dzisiaj As Date

    dzisiaj = Date

    ' TODO: przypisanie ścieżek i właściwej nazwy pliku
    ' TODO: utworzenie skoroszytu z szablonu
    ' TODO: zapisanie pliku w katalogu docelowym

End Sub

W kolejnych sekcjach ten „TODO-list” zamieni się w gotowy kod.

Podstawowe metody i funkcje, które będziesz wykorzystywać

Makro tworzące skoroszyt z szablonu obraca się wokół kilku kluczowych metod Excela i VBA:

  • Workbooks.Add – tworzy nowy skoroszyt (zwykły lub z szablonu),
  • Workbook.SaveAs – zapisuje skoroszyt pod podaną nazwą i ścieżką,
  • Format – formatuje daty i liczby na tekst do użycia w nazwie pliku,
  • Dir – sprawdza, czy plik/folder istnieje,
  • MsgBox – pokazuje komunikaty dla użytkownika (błędy, potwierdzenia).

Nie ma tu zaawansowanego VBA – to nadal spokojny poziom „po pracy w piątek po 16:00”.

Programista z brodą w słuchawkach piszący kod na laptopie w biurze
Źródło: Pexels | Autor: cottonbro studio

Najprostsze makro: tworzenie nowego, pustego skoroszytu (bez szablonu)

Dlaczego zacząć od pustego skoroszytu

Zanim do gry wejdą ścieżki sieciowe i szablony, dobrze jest sprawdzić, czy samo tworzenie nowego pliku działa bezbłędnie. Taki „suchy trening” pozwala:

  • upewnić się, że Excel w ogóle wykonuje makra,
  • zobaczyć, jak zachowują się obiekty Workbook i ActiveWorkbook,
  • przećwiczyć zapis nowego pliku do wybranego katalogu.

Jeżeli to zadziała, przejście na wersję z szablonem jest dużo prostsze – zmienia się tylko sposób wywołania Workbooks.Add.

Makro tworzące i zapisujące pusty skoroszyt

Poniższy przykład tworzy pusty skoroszyt, nadaje mu nazwę z datą i zapisuje go w folderze obok pliku z makrem:

Sub UtworzPustySkoroszyt()

    Dim wbNowy As Workbook
    Dim sciezkaDocelowa As String
    Dim nazwaPliku As String
    Dim dzisiaj As Date

    dzisiaj = Date

    ' 1. Ścieżka do folderu, w którym zapisany jest plik z makrem
    sciezkaDocelowa = ThisWorkbook.Path & ""

    ' 2. Nazwa pliku z datą w formacie RRRR-MM-DD
    nazwaPliku = "NowyPlik_" & Format(dzisiaj, "yyyy-mm-dd") & ".xlsx"

    ' 3. Utworzenie pustego skoroszytu
    Set wbNowy = Workbooks.Add

    ' 4. Zapisanie nowego skoroszytu
    wbNowy.SaveAs Filename:=sciezkaDocelowa & nazwaPliku, _
                  FileFormat:=xlOpenXMLWorkbook   ' .xlsx

    ' 5. Informacja dla użytkownika
    MsgBox "Utworzono plik: " & vbCrLf & sciezkaDocelowa & nazwaPliku, _
           vbInformation, "Gotowe"

End Sub

Jeśli ten kod działa poprawnie, wiesz już, że:

  • Excel potrafi tworzyć nowe pliki,
  • ścieżka ThisWorkbook.Path zwraca sensowny katalog,
  • nie ma konfliktów z uprawnieniami do zapisu w tej lokalizacji.

Dodanie prostego zabezpieczenia przed nadpisaniem pliku

W wersji minimalnej makro nadpisze istniejący plik bez pytania. Żeby uniknąć nieprzyjemnych niespodzianek, można użyć funkcji Dir do sprawdzenia, czy plik już istnieje:

Sub UtworzPustySkoroszytBezNadpisania()

    Dim wbNowy As Workbook
    Dim sciezkaDocelowa As String
    Dim nazwaPliku As String
    Dim dzisiaj As Date

    dzisiaj = Date
    sciezkaDocelowa = ThisWorkbook.Path & ""
    nazwaPliku = "NowyPlik_" & Format(dzisiaj, "yyyy-mm-dd") & ".xlsx"

    ' Sprawdzamy, czy plik już istnieje
    If Dir(sciezkaDocelowa & nazwaPliku) <> "" Then
        MsgBox "Plik o nazwie " & nazwaPliku & " już istnieje." & vbCrLf & _
               "Zmień nazwę lub usuń stary plik.", vbExclamation, "Uwaga"
        Exit Sub
    End If

    Set wbNowy = Workbooks.Add

    wbNowy.SaveAs Filename:=sciezkaDocelowa & nazwaPliku, _
                  FileFormat:=xlOpenXMLWorkbook

    MsgBox "Utworzono nowy plik: " & nazwaPliku, vbInformation, "Gotowe"

End Sub

W wersji „dla odważnych” można zamiast tego automatycznie dodać sufiks _1, _2 itd., ale do pracy z szablonem nie jest to konieczne.

Programista piszący makro VBA przy dwóch monitorach w nowoczesnym biurze
Źródło: Pexels | Autor: Mikhail Nilov

Tworzenie skoroszytu na podstawie szablonu – główna logika makra

Metoda Workbooks.Add z użyciem szablonu

Metoda Workbooks.Add przyjmuje parametr Template, do którego można podać ścieżkę do pliku szablonu. Ogólny schemat jest bardzo prosty:

Set wbNowy = Workbooks.Add(Template:="C:SciezkaRaportSprzedaz.xltx")

Excel otwiera wtedy nowy skoroszyt na podstawie wskazanego pliku. Sam szablon pozostaje niezmieniony. Można to traktować jak „Zapisz jako…” wykonywane automatycznie w tle.

Pełne makro: szablon obok pliku z makrem

Najwygodniejszy układ na początek: plik z makrem i szablon leżą w tym samym folderze. Dzięki temu nie trzeba ustalać skomplikowanych ścieżek sieciowych.

Sub UtworzRaportZSablonu()

    Dim sciezkaFolderu As String
    Dim sciezkaSzablonu As String
    Dim sciezkaDocelowa As String
    Dim nazwaSzablonu As String
    Dim nazwaPliku As String
    Dim wbNowy As Workbook
    Dim dzisiaj As Date

    dzisiaj = Date

    ' Folder, w którym znajduje się plik z makrem
    sciezkaFolderu = ThisWorkbook.Path & ""

    ' Nazwa pliku szablonu (leży w tym samym folderze)
    nazwaSzablonu = "Szablon_RaportSprzedaz.xltx"

    sciezkaSzablonu = sciezkaFolderu & nazwaSzablonu

    ' Sprawdzenie, czy szablon istnieje
    If Dir(sciezkaSzablonu) = "" Then
        MsgBox "Nie znaleziono szablonu:" & vbCrLf & sciezkaSzablonu, _
               vbCritical, "Brak szablonu"
        Exit Sub
    End If

    ' Folder docelowy ten sam, co folder z makrem (na start)
    sciezkaDocelowa = sciezkaFolderu

    ' Docelowa nazwa pliku
    nazwaPliku = "Raport_sprzedazy_" & Format(dzisiaj, "yyyy-mm-dd") & ".xlsx"

    ' Sprawdzenie, czy plik docelowy już istnieje
    If Dir(sciezkaDocelowa & nazwaPliku) <> "" Then
        MsgBox "Plik " & nazwaPliku & " już istnieje w tym folderze." & vbCrLf & _
               "Zmień datę lub nazwę w kodzie.", vbExclamation, "Plik istnieje"
        Exit Sub
    End If

    ' Utworzenie nowego skoroszytu na podstawie szablonu
    Set wbNowy = Workbooks.Add(Template:=sciezkaSzablonu)

    ' Zapis nowego skoroszytu jako zwykły .xlsx
    wbNowy.SaveAs Filename:=sciezkaDocelowa & nazwaPliku, _
                  FileFormat:=xlOpenXMLWorkbook

    ' Komunikat dla użytkownika
    MsgBox "Utworzono raport: " & vbCrLf & sciezkaDocelowa & nazwaPliku, _
           vbInformation, "Raport gotowy"

End Sub

Ten wariant sprawdza się w małych zespołach albo dla jednej osoby. Kartka samoprzylepna z napisem „Szablon musi się nazywać Szablon_RaportSprzedaz.xltx” rozwiązuje połowę problemów organizacyjnych.

Wersja sieciowa: szablon na wspólnym dysku

W firmowej rzeczywistości szablon najczęściej ląduje na dysku sieciowym. Wtedy ścieżkę zapisuje się jako UNC:

serwerdzialRaportySzablonySzablon_RaportSprzedaz.xltx

Makro różni się tylko sposobem ustalenia sciezkaSzablonu i sciezkaDocelowa:

Sub UtworzRaportZSablonuSiec()

    Dim sciezkaSzablonu As String
    Dim sciezkaDocelowa As String
    Dim nazwaPliku As String
    Dim wbNowy As Workbook
    Dim dzisiaj As Date

    dzisiaj = Date

    ' Stała ścieżka do szablonu na dysku sieciowym
    sciezkaSzablonu = "serwerdzialRaportySzablonySzablon_RaportSprzedaz.xltx"

    ' Folder docelowy – np. folder z raportami bieżącego roku
    sciezkaDocelowa = "serwerdzialRaporty" & Year(dzisiaj) & ""

    ' Sprawdzenie szablonu
    If Dir(sciezkaSzablonu) = "" Then
        MsgBox "Nie znaleziono szablonu:" & vbCrLf & sciezkaSzablonu, _
               vbCritical, "Brak szablonu"
        Exit Sub
    End If

    ' Prosta weryfikacja katalogu docelowego
    If Dir(sciezkaDocelowa, vbDirectory) = "" Then
        MsgBox "Folder docelowy nie istnieje:" & vbCrLf & sciezkaDocelowa, _
               vbCritical, "Brak folderu"
        Exit Sub
    End If

    nazwaPliku = "Raport_sprzedazy_" & Format(dzisiaj, "yyyy-mm-dd") & ".xlsx"

    If Dir(sciezkaDocelowa & nazwaPliku) <> "" Then
        MsgBox "Plik " & nazwaPliku & " już istnieje w folderze:" & vbCrLf & _
               sciezkaDocelowa, vbExclamation, "Plik istnieje"
        Exit Sub
    End If

    Set wbNowy = Workbooks.Add(Template:=sciezkaSzablonu)

    wbNowy.SaveAs Filename:=sciezkaDocelowa & nazwaPliku, _
                  FileFormat:=xlOpenXMLWorkbook

    MsgBox "Utworzono raport w folderze:" & vbCrLf & _
           sciezkaDocelowa & nazwaPliku, vbInformation, "Gotowe"

End Sub

W takiej konfiguracji zmiana szablonu (np. nowa wersja raportu) sprowadza się do podmiany jednego pliku w folderze Szablony. Makra użytkowników zostają nietknięte.

Automatyczna data i numeracja w pliku z szablonu

Drobny dodatek, który często bywa wymagany: oprócz daty w nazwie pliku trzeba umieścić datę i numer raportu w konkretnych komórkach. Skoro i tak mamy referencję wbNowy, można to załatwić w dwóch linijkach.

Przykład zakłada, że w szablonie:

  • w komórce B2 ma się znaleźć data raportu,
  • Uzupełnianie danych w nowym skoroszycie z poziomu makra

    Szablon to punkt wyjścia, ale w praktyce nowy raport powinien od razu zawierać kilka podstawowych informacji. Zamiast kazać użytkownikowi pamiętać o wszystkim, można część danych wstawić automatycznie:

  • datę sporządzenia raportu,
  • numer raportu lub miesiąc/kwartał,
  • nazwę użytkownika (albo działu),
  • rok lub zakres raportowania.

Poniższy przykład nawiązuje do wcześniejszego makra sieciowego. Po utworzeniu skoroszytu wstawia datę i numer raportu w konkretne komórki oraz autora raportu na podstawie loginu z Windows.

Sub UtworzRaportZSablonuSiec_DaneNaglowka()

    Dim sciezkaSzablonu As String
    Dim sciezkaDocelowa As String
    Dim nazwaPliku As String
    Dim wbNowy As Workbook
    Dim dzisiaj As Date
    Dim numerRaportu As String
    Dim uzytkownik As String

    dzisiaj = Date

    sciezkaSzablonu = "serwerdzialRaportySzablonySzablon_RaportSprzedaz.xltx"
    sciezkaDocelowa = "serwerdzialRaporty" & Year(dzisiaj) & ""

    If Dir(sciezkaSzablonu) = "" Then
        MsgBox "Nie znaleziono szablonu:" & vbCrLf & sciezkaSzablonu, _
               vbCritical, "Brak szablonu"
        Exit Sub
    End If

    If Dir(sciezkaDocelowa, vbDirectory) = "" Then
        MsgBox "Folder docelowy nie istnieje:" & vbCrLf & sciezkaDocelowa, _
               vbCritical, "Brak folderu"
        Exit Sub
    End If

    nazwaPliku = "Raport_sprzedazy_" & Format(dzisiaj, "yyyy-mm-dd") & ".xlsx"

    If Dir(sciezkaDocelowa & nazwaPliku) <> "" Then
        MsgBox "Plik " & nazwaPliku & " już istnieje.", vbExclamation, "Plik istnieje"
        Exit Sub
    End If

    ' Przykładowy numer raportu: RRRR-MM-001
    numerRaportu = Year(dzisiaj) & "-" & Format(Month(dzisiaj), "00") & "-001"

    ' Nazwa użytkownika z Windows (czasem idealna, czasem mniej…)
    uzytkownik = Environ$("Username")

    Set wbNowy = Workbooks.Add(Template:=sciezkaSzablonu)

    With wbNowy.Worksheets(1)
        ' B2 – data raportu
        .Range("B2").Value = dzisiaj
        .Range("B2").NumberFormat = "yyyy-mm-dd"

        ' B3 – numer raportu
        .Range("B3").Value = numerRaportu

        ' B4 – autor raportu
        .Range("B4").Value = uzytkownik
    End With

    wbNowy.SaveAs Filename:=sciezkaDocelowa & nazwaPliku, _
                  FileFormat:=xlOpenXMLWorkbook

    MsgBox "Raport utworzony i uzupełniony danymi nagłówka:" & vbCrLf & _
           sciezkaDocelowa & nazwaPliku, vbInformation, "Raport gotowy"

End Sub

W szablonie wystarczy opisać komórki B2–B4 („Data raportu”, „Numer raportu”, „Autor”) i zostawić je puste. Resztę zrobi makro.

Parametryzacja: wybór miesiąca lub okresu raportu

Czasem raport trzeba przygotować nie „na dziś”, ale dla konkretnego miesiąca. Zamiast ręcznie edytować makro przed każdym uruchomieniem, można zapytać użytkownika o okres raportu przy pomocy InputBox.

Sub UtworzRaportDlaWybranegoMiesiaca()

    Dim sciezkaSzablonu As String
    Dim sciezkaDocelowa As String
    Dim wbNowy As Workbook
    Dim rokRaportu As Long
    Dim miesiacRaportu As Long
    Dim odpowiedz As String
    Dim nazwaPliku As String

    ' Pobranie roku
PytajRok:
    odpowiedz = InputBox("Podaj rok raportu (np. 2024):", "Rok raportu")

    If odpowiedz = "" Then Exit Sub   ' użytkownik kliknął Anuluj

    If Not IsNumeric(odpowiedz) Then
        MsgBox "Rok musi być liczbą.", vbExclamation, "Błędne dane"
        GoTo PytajRok
    End If

    rokRaportu = CLng(odpowiedz)
    If rokRaportu < 2000 Or rokRaportu > Year(Date) + 1 Then
        MsgBox "Rok raportu poza zakresem.", vbExclamation, "Błędny rok"
        GoTo PytajRok
    End If

    ' Pobranie miesiąca
PytajMiesiac:
    odpowiedz = InputBox("Podaj miesiąc raportu (1-12):", "Miesiąc raportu")

    If odpowiedz = "" Then Exit Sub

    If Not IsNumeric(odpowiedz) Then
        MsgBox "Miesiąc musi być liczbą od 1 do 12.", vbExclamation, "Błędne dane"
        GoTo PytajMiesiac
    End If

    miesiacRaportu = CLng(odpowiedz)
    If miesiacRaportu < 1 Or miesiacRaportu > 12 Then
        MsgBox "Miesiąc musi być w zakresie 1-12.", vbExclamation, "Błędne dane"
        GoTo PytajMiesiac
    End If

    ' Ścieżki – przykład sieciowy
    sciezkaSzablonu = "serwerdzialRaportySzablonySzablon_RaportSprzedaz.xltx"
    sciezkaDocelowa = "serwerdzialRaporty" & rokRaportu & ""

    If Dir(sciezkaSzablonu) = "" Then
        MsgBox "Brak szablonu:" & vbCrLf & sciezkaSzablonu, vbCritical, "Błąd"
        Exit Sub
    End If

    If Dir(sciezkaDocelowa, vbDirectory) = "" Then
        MsgBox "Folder docelowy nie istnieje:" & vbCrLf & sciezkaDocelowa, _
               vbCritical, "Brak folderu"
        Exit Sub
    End If

    nazwaPliku = "Raport_sprzedazy_" & rokRaportu & "_" & _
                 Format(miesiacRaportu, "00") & ".xlsx"

    If Dir(sciezkaDocelowa & nazwaPliku) <> "" Then
        MsgBox "Plik " & nazwaPliku & " już istnieje.", _
               vbExclamation, "Plik istnieje"
        Exit Sub
    End If

    Set wbNowy = Workbooks.Add(Template:=sciezkaSzablonu)

    With wbNowy.Worksheets(1)
        ' B2 – okres raportu, np. 2024-03
        .Range("B2").Value = rokRaportu & "-" & Format(miesiacRaportu, "00")
        ' B3 – opis słowny
        .Range("B3").Value = "Raport za " & _
                             LCase(Format(DateSerial(rokRaportu, miesiacRaportu, 1), "mmmm")) & _
                             " " & rokRaportu
    End With

    wbNowy.SaveAs Filename:=sciezkaDocelowa & nazwaPliku, _
                  FileFormat:=xlOpenXMLWorkbook

    MsgBox "Utworzono raport: " & nazwaPliku, vbInformation, "Gotowe"

End Sub

Takie podejście dobrze sprawdza się w działach finansowych i kontrolingu, gdzie z jednego szablonu powstaje cały zestaw raportów miesięcznych.

Zarządzanie ścieżkami i nazwami plików – wersja praktyczna

Stałe na górze modułu zamiast „magicznych” ścieżek

W kodzie szybko pojawia się kilka podobnych ścieżek: do szablonu, do raportów, czasem do archiwum. Zamiast wpisywać je w wielu miejscach, lepiej użyć stałych zadeklarowanych na górze modułu. Dzięki temu przy zmianie lokalizacji nie trzeba robić wycieczki po całym kodzie.

Option Explicit

' Stałe konfiguracyjne – do edycji przez "opiekuna" makra
Public Const SCIEZKA_SZABLONY As String = _
    "serwerdzialRaportySzablony"
Public Const NAZWA_SZABLONU_RAPORT As String = _
    "Szablon_RaportSprzedaz.xltx"
Public Const SCIEZKA_RAPORTY As String = _
    "serwerdzialRaporty"

Właściwe makro staje się krótsze i czytelniejsze:

Sub UtworzRaportZKonfiguracji()

    Dim sciezkaSzablonu As String
    Dim sciezkaDocelowa As String
    Dim wbNowy As Workbook
    Dim dzisiaj As Date
    Dim nazwaPliku As String

    dzisiaj = Date

    sciezkaSzablonu = SCIEZKA_SZABLONY & NAZWA_SZABLONU_RAPORT
    sciezkaDocelowa = SCIEZKA_RAPORTY & Year(dzisiaj) & ""

    If Dir(sciezkaSzablonu) = "" Then
        MsgBox "Brak szablonu: " & sciezkaSzablonu, vbCritical, "Błąd"
        Exit Sub
    End If

    If Dir(sciezkaDocelowa, vbDirectory) = "" Then
        MsgBox "Brak folderu raportów: " & sciezkaDocelowa, vbCritical, "Błąd"
        Exit Sub
    End If

    nazwaPliku = "Raport_sprzedazy_" & Format(dzisiaj, "yyyy-mm-dd") & ".xlsx"

    If Dir(sciezkaDocelowa & nazwaPliku) <> "" Then
        MsgBox "Plik już istnieje: " & nazwaPliku, vbExclamation, "Konflikt nazw"
        Exit Sub
    End If

    Set wbNowy = Workbooks.Add(Template:=sciezkaSzablonu)

    wbNowy.SaveAs Filename:=sciezkaDocelowa & nazwaPliku, _
                  FileFormat:=xlOpenXMLWorkbook

    MsgBox "Raport utworzony: " & sciezkaDocelowa & nazwaPliku, _
           vbInformation, "Gotowe"

End Sub

Jeśli ktoś w IT przeniesie folder „Raporty” na inny serwer, wystarczy poprawić jedną stałą. Bez przekopywania kilkunastu procedur.

Automatyczne dopisywanie sufiksu, gdy plik już istnieje

W wersji „dla ostrożnych” makro zatrzymuje się, gdy plik o danej nazwie już istnieje. Czasem jednak wygodniej jest, aby tworzyło kolejną wersję z automatycznym sufiksem (_1, _2…). Użytkownik nie musi wtedy obchodzić problemu ręcznie.

Function ZnajdzDostepnaNazwe( _
        ByVal sciezkaFolderu As String, _
        ByVal nazwaBazowa As String, _
        ByVal rozszerzenie As String) As String
    ' Zwraca pierwszą wolną nazwę w postaci:
    ' nazwaBazowa.ext, nazwaBazowa_1.ext, nazwaBazowa_2.ext, ...

    Dim pelnaSciezka As String
    Dim licznik As Long

    ' Najpierw próbujemy bez sufiksu
    pelnaSciezka = sciezkaFolderu & nazwaBazowa & rozszerzenie

    If Dir(pelnaSciezka) = "" Then
        ZnajdzDostepnaNazwe = pelnaSciezka
        Exit Function
    End If

    ' Jeśli istnieje – dokładamy kolejne numery
    licznik = 1
    Do
        pelnaSciezka = sciezkaFolderu & nazwaBazowa & "_" & licznik & rozszerzenie
        If Dir(pelnaSciezka) = "" Then
            ZnajdzDostepnaNazwe = pelnaSciezka
            Exit Function
        End If
        licznik = licznik + 1
        ' Gdyby ktoś naprawdę robił 1000 raportów dziennie...
        If licznik > 1000 Then Exit Do
    Loop

    ZnajdzDostepnaNazwe = ""   ' nie udało się
End Function

Funkcję można wykorzystać w głównym makrze:

Sub UtworzRaportZSufiksem()

    Dim sciezkaSzablonu As String
    Dim sciezkaFolderu As String
    Dim wbNowy As Workbook
    Dim dzisiaj As Date
    Dim nazwaBazowa As String
    Dim pelnaSciezkaDocelowa As String

    dzisiaj = Date

    sciezkaSzablonu = SCIEZKA_SZABLONY & NAZWA_SZABLONU_RAPORT
    sciezkaFolderu = SCIEZKA_RAPORTY & Year(dzisiaj) & ""

    If Dir(sciezkaSzablonu) = "" Then
        MsgBox "Brak szablonu: " & sciezkaSzablonu, vbCritical, "Błąd"
        Exit Sub
    End If

    If Dir(sciezkaFolderu, vbDirectory) = "" Then
        MsgBox "Brak folderu docelowego: " & sciezkaFolderu, vbCritical, "Błąd"
        Exit Sub
    End If

    nazwaBazowa = "Raport_sprzedazy_" & Format(dzisiaj, "yyyy-mm-dd")

    pelnaSciezkaDocelowa = ZnajdzDostepnaNazwe( _
                               sciezkaFolderu, _
                               nazwaBazowa, _
                               ".xlsx")

    If pelnaSciezkaDocelowa = "" Then
        MsgBox "Nie udało się znaleźć wolnej nazwy pliku.", _
               vbCritical, "Błąd nazwy"
        Exit Sub
    End If

    Set wbNowy = Workbooks.Add(Template:=sciezkaSzablonu)

    wbNowy.SaveAs Filename:=pelnaSciezkaDocelowa, _
                  FileFormat:=xlOpenXMLWorkbook

    MsgBox "Utworzono raport: " & vbCrLf & pelnaSciezkaDocelowa, _
           vbInformation, "Gotowe"

End Sub

Jeśli w folderze istnieje już Raport_sprzedazy_2024-04-15.xlsx, makro utworzy kolejno Raport_sprzedazy_2024-04-15_1.xlsx, potem _2 itd. Działy sprzedaży lubią to rozwiązanie – każdy handlowiec może wygenerować „swoją” wersję raportu bez obawy o nadpisanie cudzego pliku.

Wybór folderu docelowego przez użytkownika (FileDialog)

Dla użytkowników, którzy wolą sami decydować, gdzie zapisać raport, przydaje się okno wyboru folderu. Excel udostępnia do tego Application.FileDialog z typem msoFileDialogFolderPicker.

Najczęściej zadawane pytania (FAQ)

Jak napisać makro, które tworzy nowy skoroszyt na podstawie szablonu?

Najprostszy schemat to użycie metody Workbooks.Add z podaniem pełnej ścieżki do szablonu. Przykładowy kod:

Sub NowyRaport()
  Dim wb As Workbook
  Set wb = Workbooks.Add(Filename:="C:SzablonyRaport_dzienny.xltx")
  wb.SaveAs "C:RaportyRaport_dzienny_" & Format(Date, "yyyy-mm-dd") & ".xlsx"
End Sub

W praktyce do tego dokładamy jeszcze obsługę błędów (gdy szablon zniknie) i ewentualne pytania do użytkownika o nazwę pliku lub folder docelowy.

Gdzie najlepiej zapisać szablon Excela używany przez makro?

Dla jednego użytkownika najprościej zapisać szablon lokalnie, np. w folderze C:Szablony lub w domyślnym folderze szablonów Excela. Dzięki temu nie ma problemu z dostępem do pliku, o ile nie zmieni się ścieżka.

Dla zespołu wygodniej jest użyć wspólnego zasobu sieciowego, np. SerwerDzialSzablonyRaport.xltx. Wtedy wszyscy korzystają z tej samej, aktualnej wersji wzorca. W środowisku Microsoft 365 rolę „wspólnego dysku” często przejmuje SharePoint lub OneDrive dla Firm – makro nadal odwołuje się do zwykłej ścieżki folderu.

Czym różni się makro z szablonem od ręcznego „Zapisz jako kopia” starego pliku?

Przy „Zapisz jako kopia” użytkownik pracuje na zwykłym pliku, który łatwo omyłkowo nadpisać lub zmodyfikować w zły sposób (usunięte formuły, pozmieniane arkusze itp.). Za każdym razem trzeba też ręcznie dbać o nazwę pliku i właściwy folder.

Makro z szablonem zawsze startuje od czystego, nienaruszonego wzorca. Automatycznie tworzy nowy skoroszyt, nadaje spójną nazwę (np. z datą) i może wymusić zapis w określonej lokalizacji. Użytkownik wciska skrót klawiaturowy, a reszta „magii” dzieje się sama – co ogranicza pole do popisów błędów ludzkich.

Kiedy powinienem użyć szablonu .xltx, a kiedy .xltm w makrze?

Jeśli nowy skoroszyt ma służyć wyłącznie do wprowadzania danych i prostych obliczeń, a cały kod VBA siedzi w osobnym „panelu” (np. w pliku PanelRaportów.xlsm), wystarczy szablon .xltx. To bezpieczniejsze rozwiązanie przy wysyłaniu plików mailem i u użytkowników z zablokowanymi makrami.

Szablon .xltm wybierz wtedy, gdy nowo utworzony skoroszyt ma zawierać własne makra: przyciski z logiką, zdarzenia (np. Worksheet_Change), funkcje użytkownika. Innymi słowy – gdy raport ma być „inteligentny”, a nie tylko ładnie sformatowany.

Jak w makrze sprawdzić, czy szablon istnieje i obsłużyć błąd, gdy go brakuje?

Najprościej użyć funkcji sprawdzającej istnienie pliku przed wywołaniem Workbooks.Add. Przykład:

Function PlikIstnieje(ByVal sciezka As String) As Boolean
  PlikIstnieje = (Dir(sciezka) <> "")
End Function

Sub NowyRaportZSzablonu()
  Dim sciezkaSzablonu As String
  sciezkaSzablonu = "C:SzablonyRaport.xltx"

  If Not PlikIstnieje(sciezkaSzablonu) Then
    MsgBox "Nie znaleziono szablonu:" & vbCrLf & sciezkaSzablonu, vbCritical
    Exit Sub
  End If
  ' tu dopiero Workbooks.Add …
End Sub

Dzięki temu makro nie zawiesi się efektownym błędem w środku pracy działu, tylko grzecznie zgłosi problem i przerwie działanie.

Czy da się podpiąć makro tworzące skoroszyt z szablonu pod przycisk lub skrót klawiaturowy?

Tak, to standardowa praktyka. Makro możesz przypiąć do:

  • przycisku formularza w arkuszu (Wstaw → Formanty formularza → Przyciski),
  • ikony na pasku szybkiego dostępu (Plik → Opcje → Pasek narzędzi Szybki dostęp → Dodaj makro),
  • skrótów klawiaturowych przez okno Makra → Opcje (np. Ctrl+Shift+R).

Dzięki temu użytkownik nie musi znać VBA ani szukać plików po folderach – wciska „swój” skrót i po chwili ma przed sobą nowy, gotowy do pracy raport.

Czy makro może automatycznie nadawać nazwę nowemu plikowi (np. z datą lub numerem raportu)?

Tak, to jedna z głównych zalet takiego rozwiązania. Nazwę można zbudować dynamicznie z daty, godziny, inicjałów użytkownika lub numeru wersji. Prosty przykład:

Dim nazwaPliku As String
nazwaPliku = "Raport_sprzedazy_" & Format(Date, "yyyy-mm-dd") & ".xlsx"
ActiveWorkbook.SaveAs "C:Raporty" & nazwaPliku

W bardziej rozbudowanych scenariuszach nazwa może zawierać miesiąc raportowania, kod działu czy numer projektu. Efekt uboczny jest całkiem przyjemny: koniec z tajemniczymi plikami typu Nowy skoroszyt (2).xlsx.