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.

[Excel] Pobieranie danych z zamknietych plików

Gamblee 31 Paź 2011 23:57 8567 14
  • #1 31 Paź 2011 23:57
    Gamblee
    Poziom 9  

    Cześć,
    Chciałbym stworzyć makro, które pobiera pewien zakres danych i wkleja do jednego pliku. Chciałbym, żeby to odbywało się automatycznie, gdyż dziennie takich plików jest około 120.

    1. Pliki mają zawsze datę na końcu, czyli z dzisiaj było by ...31.10.2011.xls
    2. Pliki zawsze są umieszczane w jednym folderze - np. c:\dane\

    Zrobienie makra, żeby otwierał jeden plik nie jest problemem. Gorzej jak ma pobrać z kilku. Na forum czytałem gdzieś o funkcji FileSearch, ale wyskakuje mi jakiś bład (nie wiem czy to wina VBA v.7 - tamten temat był z przed dwóch lat).

    Na razie mam coś takiego:

    Kod: vb
    Zaloguj się, aby zobaczyć kod

    0 14
  • Pomocny post
    #2 01 Lis 2011 07:23
    adamas_nt
    Moderator Programowanie

    Osobiście wolę korzystać z funkcji Dir. FileSerch potrzebuje referencji i lubi stwarzać problemy.
    Poniżej przykład z pętlą. Jeśli daty w nazwach są w stałym formacie można sobie ułatwić podstawiając dzisiejszą datę. Dla wczoraj będzie to Date-1, itd Oczywiście dla wielu plików przypisanie nazwy odbywać się będzie wewnątrz pętli bez wychodzenia, ale z tym sobie pewnie poradzisz.
    Jeśli nie kopiujesz formatu komórki wystarczy przypisanie.

    Kod: vb
    Zaloguj się, aby zobaczyć kod

    0
  • #3 01 Lis 2011 14:32
    Gamblee
    Poziom 9  

    Chciałbym, żeby to makro wyszukiwało mi ostatni wolny wiersz i tam wklejało dane z plików, czyli:

    Kod: vb
    Zaloguj się, aby zobaczyć kod

    Niestety moja znajomość VBA jest na razie (mam nadzieje :D ) na niskim poziomie i dołączenie tej części kodu wywala mi błąd.

    Druga rzecz. Pobierane dane nie zawsze są tej samej długości. Czyli z jednego pliku 25 wierszy, a z drugiego 10. Dane mają być pobierane też z kilku kolumn. Chciałbym więc mieć możliwość ominięcia, np kolumny C.
    W załączniku jest przykład pliku, z którego chce pobierać dane.

    0
  • #5 06 Lis 2011 12:20
    Gamblee
    Poziom 9  

    Kod: vb
    Zaloguj się, aby zobaczyć kod


    Chciałbym trochę poprawić to makro, a mianowicie:
    1. Teraz kopiuje mi komórki z zakresu C7:O81. Chciałbym aby były to tylko komórki niepuste. Mógłbym dodać, żeby szukał ostatniej nie pustej w kolumnie C. Jeśli tak to, w którym miejscu najlepiej to zrobić?
    2. Czas działania danego makra też pozostawia dużo do życzenia. Dziennie kopiowanych jest około 10 tysięcy wierszy. Na pewno było by ich mniej gdyby nie kopiowało pustych, wtedy około 4-5 tysięcy. Czytałem, że ReDim Preserve pochłania dużo pamięci i spowalnia cały proces.

    Zastanawiam się nad wstawieniem tego:
    Kod: vb
    Zaloguj się, aby zobaczyć kod

    0
  • #6 06 Lis 2011 18:14
    adamas_nt
    Moderator Programowanie

    Musiałbyś zmienić licznik pętli zmiennej wiersza:
    For k = 1 To ostatnia komórka
    Range(wiele_kolumn).End przeszukuje tylko skrajną, lewą kolumnę. Wyszukuj od pojedynczej i najlepiej od dołu (jeśli zdarzają się "okienka"). Np ostWrs=Range("B65536")>End(xlup).row

    Inne sposoby
    ostW=ActiveSheet.UsedRange.Rows.Count
    ostW=Columns(2).Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

    Działanie z tablicą jest dość szybkie. Zmiana rozmiaru (redim) praktycznie nie wpływa na czas działania. Przy przepisywaniu z tablicy można sporo zaoszczędzić wyłączając odświeżanie. Nie zaszkodzi wyłączyć dla całej procedury:
    Application.screenupdating=False i na końcu =True

    0
  • #7 06 Lis 2011 19:23
    Gamblee
    Poziom 9  

    Pomógłbyś mi przerobić to makro przy założeniach:
    1. Ma pobierać wszystkie pliki *.xls i *.xlsx z folderu - na szczęście to makro już to potrafi;
    2. Z arkusza "Ogólne" pobiera imię pracownika z komórki A1, która jest scalona z trzech komórek. Przy próbie zmodyfikowania makra, zaczęło mi pobierać wszystkie 3 i wklejać od kolumny A do C.
    3. Z arkusza "Dane" pobiera dane z zakresu C7:O81, pomijając puste wiersze na podstawie kolumny C.
    4. Wklejać to do nowego skoroszytu bez żadnych odstępów.

    I teraz najgorsze. W tym momencie imię pracownika w nowym skoroszycie jest w kolumnie A, następnie dane są wklejane od kolumny B. Chciałbym, żeby tak zostało. Dodatkowo obecnie imię przypisywane jest do każdego "rekordu" ze skoroszytu danego pracownika:

    A B C
    Imie 1 10 xxx
    Imie 1 20 xxx
    Imie 1 20 xxx
    Imie 2 20 xxx
    Imie 2 30 xxx
    Imie 3 10 xxx
    Imie 3 15 xxx

    0
  • #9 06 Lis 2011 21:29
    Gamblee
    Poziom 9  

    Dzięki wielkie. Imię dodaje tylko do pierwszego wiersza z danego skoroszytu. Ale najważniejsza jest prędkość. Zrobię testy i zaprezentuje wyniki:)

    Czas na wyniki testu:ść
    Ilość plików: 142
    stare makro:
    1. wczytywanie z formularzy: 35sek
    2. Dodawanie: 1min 2sek
    Nowe makro:
    1. wczytanie plus dodanie 20sek :D

    Podsumowanie:
    Podczas używania starego makra musiałem używać dodatkowego makra, które usuwało puste wiersze. Dopóki nie uporam się z dodawaniem imienia do każdego wiersza z tego samego formularza będę to musiał robić albo ręcznie albo korzystać z kolejnego makra, bądź poprawić to (co jest mało prawdopodobne :| )

    Jeszcze raz WIELKIE DZIĘKI :!:

    0
  • #10 06 Lis 2011 21:55
    adamas_nt
    Moderator Programowanie

    Wyrzuć deklarację tablicy i przypisanie rozmiaru (ostało się), linia: i = i + 1 też niepotrzebna...

    0
  • #11 06 Lis 2011 22:00
    Gamblee
    Poziom 9  

    adamas_nt napisał:
    Wyrzuć deklarację tablicy i przypisanie rozmiaru (ostało się), linia: i = i + 1 też niepotrzebna...


    Czyli? Nie chce usunąć czegoś co jest potrzebne.

    0
  • Pomocny post
    #12 07 Lis 2011 09:10
    adamas_nt
    Moderator Programowanie

    Usuń:
    kom() As Variant
    ReDim kom(22, 1) As Variant
    i = i + 1

    0
  • #13 07 Lis 2011 22:48
    Gamblee
    Poziom 9  

    A mógłbyś mi jeszcze pomóc z tym automatycznym przepisywaniem imienia z pierwszego wiersza każdej tabeli do następnego imienia? Chciałem na koniec zastosować funkcje autofill, ale zmienna jest ilość wierszy. Chyba, że dało by rade zrobić to od razu wklejając arkusze.

    0
  • Pomocny post
    #14 08 Lis 2011 07:23
    adamas_nt
    Moderator Programowanie

    Najprościej. Tę linię

    Code:
    wkb.Sheets(ark).Cells(ostWrs, 1) = ActiveWorkbook.Sheets("Ogólne").Range("A1")
    
    przesuń do bloku pętli For j
    Kod: vb
    Zaloguj się, aby zobaczyć kod

    0
  • #15 08 Lis 2011 23:56
    Gamblee
    Poziom 9  

    Super. Działa wyśmienicie.

    1