Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

VBA - kopiowanie danych z innego pliku.

ptiger 04 Jan 2018 08:39 2463 11
  • #1
    ptiger
    Level 9  
    witam,

    Miałbym pytanie dotyczące poniższego kodu.
    Makro działa, ale za każdym razem kopiuje dane ze starych plików i z nowo dodanego, czyli jeśli pojawił się nowy plik z danymi pobiera dane z nowego i powiela dane historyczne w kolejnych wierszach.
    Jak "zmusić" makro, aby pobierało dane tylko z nowo pojawiających się plików, a nie ze wszystkich jakie znajdują się w folderze.
    kod wygląda tak:
    Code: vbscript
    Log in, to see the code
  • #2
    adamas_nt
    Moderator of Programming
    Zainteresuj się funkcją FileDateTime Link
    W pętli, w dodatkowej instrukcji warunkowej, sprawdzasz, czy datapliku > Date - ileDni
    gdzie liczba 'ileDni' decyduje o tym, czy plik są jeszcze "nowe".
  • #3
    ptiger
    Level 9  
    Poczytałem trochę o tej funkcji, odwiedziłem link i zmodyfikowałem procedurę, ale chyba nie w tym miejscu umieszczam warunek. Podczas kompilacji kodu, VBA zgłasza błąd: End If without block If.
    Możesz spojrzeć na poniższy kod:


    Code: vbscript
    Log in, to see the code
  • #4
    adamas_nt
    Moderator of Programming
    W pętli, znaczy wewnątrz, czyli w środku ;)
    Coś w tym rodzaju:
    Code: vbscript
    Log in, to see the code
  • #5
    ptiger
    Level 9  
    OK. zrozumiałem.

    Poprawiłem kod, ale dalej kopiuje wszystkie pliki z folderu, dublując je przy każdym wywołaniu makra.
  • #6
    lanzul
    Level 30  
    ptiger wrote:
    dalej kopiuje wszystkie pliki z folderu

    1. Zaprezentuj poprawiony kod
    2. Podaj parę dat z plików (utworzenia i modyfikacji)
    3. Może trzeba by trochę "wyrównać" datę uzyskaną z 'FileDateTime', np. do postaci "dd-mm-rrrr" (?):
    Code: text
    Log in, to see the code

    4. Może by zmieć zapis (?):
    Code: text
    Log in, to see the code

    na
    Code: text
    Log in, to see the code

    Chyba, że chcesz sterować "okresem karencji" definiowanym jako granica pomiędzy starym, a nowym.

    ptiger wrote:
    dublując je przy każdym wywołaniu makra

    Czyli oznacza to, że powinien być jakiś mechanizm, który będzie identyfikować, czy dany plik z katalogu został już raz "przebadany" ?
    Może odkładanie nazw plików, które zostały już kiedyś sprawdzone, w jakimś dodatkowym arkuszu ?
    Uruchamiasz makro wielokrotnie w ciągu tego samego dnia ?
  • #7
    ptiger
    Level 9  
    kod wygląda tak:
    Sub kopiaZwielu()

    Dim sciezka As String
    Dim nazwa As String
    Dim pierwszyWolnyWiersz As Long
    Dim ileDni As Integer
    Dim datapliku As Date

    sciezka = "C:\...Dane\"
    nazwa = Dir(sciezka)
    pierwszyWolnyWiersz = 2
    ileDni = 1

    Do While nazwa <> ""
    datapliku = FileDateTime(sciezka & nazwa)
    If datapliku > Date - 1 Then
    'Workbooks.Open sciezka & nazwa

    End If

    Workbooks.Open sciezka & nazwa
    Application.ScreenUpdating = False

    Range("D6:D10,D12:D19").Copy
    ThisWorkbook.Sheets(1).Range("A" & pierwszyWolnyWiersz).PasteSpecial _
    Paste:=xlPasteValues, _
    Operation:=xlNone, _
    SkipBlanks:=False, _
    Transpose:=True

    Range("G2").Copy
    ThisWorkbook.Sheets(1).Range("N" & pierwszyWolnyWiersz).PasteSpecial _
    Paste:=xlPasteValues, _
    Operation:=xlNone, _
    SkipBlanks:=False, _
    Transpose:=True

    ActiveWorkbook.Close False
    pierwszyWolnyWiersz = Range("A" & Rows.Count).End(xlUp).Row + 1
    nazwa = Dir


    Loop

    End Sub

    pliki z folderu, mają w nazwie zawsze aktualna datę utworzenia (dd-mm-yy_gg-mm).
    wydaje mi się, że FileDateTime nie jest odpowiednią funkcją, ponieważ, jak czytałem, rozpoznaje ona datę modyfikacji pliku.
    Może lepszym rozwiązaniem byłoby oparcie procedury kopiowania o datę, jaka pojawia się w nazwie pliku, tylko nie wiem czy to możliwe, bo oprócz samej daty są tam jeszcze nazwy w postaci Raport_ ...itd

    Wprowadziłem sugerowane przez Ciebie zmiany i efekt jest ten sam pliki się duplikują oprócz najstarszego (tak również było przed zmianami).

    Pozapisuję pliki przez kilka dni bez powtórnego ich otwierania i zobaczę jaki będzie efekt
  • #8
    lanzul
    Level 30  
    ptiger wrote:
    FileDateTime nie jest odpowiednią funkcją, ponieważ, jak czytałem, rozpoznaje ona datę modyfikacji pliku
    Utworzenia lub modyfikacji, zależy co późniejsze.

    Czyli nie ma innej rady ... niestety ... :) ... wsiadasz do FSO ... :) :) :) ... Nie pomyl z tym 1500/1600 ... :) ...

    ptiger wrote:
    pliki z folderu, mają w nazwie zawsze aktualna datę utworzenia (dd-mm-yy_gg-mm)
    ptiger wrote:
    Może lepszym rozwiązaniem byłoby oparcie procedury kopiowania o datę, jaka pojawia się w nazwie pliku

    Obarczysz się "powinnością" dokładnego pilnowania nazewnictwa plików, swoją drogą to jak najbardziej wskazane - i jeśli tego dokonasz, to pozyskanie daty z nazwy pliku jest jak najbardziej możliwe, różnymi drogami ... np. funkcje 'SPLIT', 'MID'.

    Ale na początek pomęcz się z FSO ... :) ...

    Zacznij od ustawienia odpowiedniej dll'ki w "systemie Excel" ... Edytor VBA => Tools\References\Microsoft Scripting Runtime

    Potem, np.:
    https://www.exceltrick.com/formulas_macros/filesystemobject-in-vba/
    https://support.microsoft.com/pl-pl/help/186118/how-to-use-filesystemobject-with-visual-basic
    itp.

    A potem "praktyka", np.:
    Code: text
    Log in, to see the code

    Jeśli chodzi o weryfikację daty to, np.:
    Code: text
    Log in, to see the code

    Można poskracać, zamiast Date użyć Now().
  • #9
    clubs
    Level 37  
    Witam
    Nie wiem czy zauważyliście ale kolega ma w kodzie błąd bo operacje dzieją się poza warunkiem
    FileDateTime zwraca date utworzenia jaki i modyfikacji i podaje tą "najmłodszą"
    Jeżeli chcesz utworzenia to tylko tak jak kolega wcześniej wspomniał DateCreated

    Code: vbscript
    Log in, to see the code
  • #10
    ptiger
    Level 9  
    lanzul wrote:
    Obarczysz się "powinnością" dokładnego pilnowania nazewnictwa plików, swoją drogą to jak najbardziej wskazane - i jeśli tego dokonasz, to pozyskanie daty z nazwy pliku jest jak najbardziej możliwe, różnymi drogami ... np. funkcje 'SPLIT', 'MID'.


    to wykonuje makro, więc o pomyłce w składni nazwy nie może być mowy,
    problem stanowi reszta podpowiedzi, ale będę walczył :)
  • #11
    lanzul
    Level 30  
    ptiger wrote:
    problem stanowi reszta podpowiedzi

    Nie ... dlaczego ?
    Code: text
    Log in, to see the code
  • #12
    ptiger
    Level 9  
    dziękuję za poświęcony czas, ale nie jestem w stanie dostosować kodu, za mało jeszcze wiem i podpowiedzi są dla mnie coraz trudniejsze.
    Muszę się douczyć.