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

Excel - Tworzenie makra - sortowanie i przenoszenie między komórkami

coobah 06 Sep 2012 23:16 7776 48
  • #31
    adamas_nt
    Moderator of Programming
    No, tak. Poprawka w linii 42. Jest:
    If Unikaty3(i - 1) = Unikaty3(i) Then

    powinno być (godzina z C i lacz z A), jeśli się nie mylę:
    Code: vbscript
    Log in, to see the code
  • Helpful post
    #32
    marek003
    Level 40  
    Nie wiem czy wolno mi zaingerować w kod, ale proponował bym w 43 linii kodu zamiast

    If Unikaty3(i - 1) = Unikaty3(i) Then


    Wprowadzić
     If Unikaty3(i - 1) = Unikaty3(i) And Unikaty1(i - 1) = Unikaty1(i) Then

    Ale może jeszcze coś nie tak zrozumiałem z kodu więc może poczekajmy na aprobate kolegi adamasa.

    Wyłapuje błąd 107027, 107068, 200, 117055, 117023, 117033

    --------------
    edit: i się spóźniłem bo sprawdzałem efekty :) Ale jak widać dobrze trafiłem :)
  • #33
    coobah
    Level 17  
    Koledzy, jesteście WIELCY!
    Wszystko śmiga jak należy! Dzięki wielkie!
    Makro wejdzie w fazę testów i w razie czego będę Was jeszcze podpytywał, bo "głowy macie nie od parady" ;)
  • #34
    coobah
    Level 17  
    Hej hej!

    Koledzy, potrzebuję pomocy :)

    Mam pliczek, który pomogliście mi ogarnąć: dostosuj.xls

    W pliczku makro wygląda następująco:

    Option Explicit
    
    Sub Dostosuj()
    Dim lista As Variant, ileWrs As Integer, idx As Integer
    Dim OstW As Long, tbl() As Variant, i As Long, j As Integer
    Dim Unikaty1 As New Collection, Unikaty2 As New Collection
    Dim Unikaty3 As New Collection, Unikaty4 As New Collection
    Dim test As New Collection, odWiersza As Integer
    
    With ThisWorkbook.Worksheets("Arkusz1")
      OstW = .Range("A1:C2").End(xlDown).Row
      Application.ScreenUpdating = False
      Sortuj (OstW)   'sortowanie
      TmToStr (OstW)  'zmiana godz na string kol.D
      lista = .Range("A1:D" & OstW)
      
      'do kolekcji nie można dodać powtarzającej się warości,
      'więc sobie przepiszemy
      For i = UBound(lista, 1) To 1 Step -1
        On Error Resume Next
        test.Add lista(i, 1) & lista(i, 2), CStr(lista(i, 1) & lista(i, 2))
      
        If Err = 0 Then
          Unikaty1.Add lista(i, 1)
          Unikaty2.Add lista(i, 2)
          Unikaty3.Add lista(i, 3)
          Unikaty4.Add lista(i, 4)
        End If
        On Error GoTo 0
      Next
      
      'umieścimy wartości w tabeli dwuwymiarowej
      'zmieniając kolejność dla poj. wiersza
      ReDim tbl(4, Unikaty1.Count)
    
      tbl(1, 1) = Unikaty1(1)
      tbl(2, 1) = Unikaty2(1)
      tbl(3, 1) = Unikaty3(1)
      tbl(4, 1) = Unikaty4(1)
      idx = 1
      
      For i = 2 To Unikaty1.Count
        If Unikaty3(i - 1) = Unikaty3(i) And Unikaty1(i - 1) = Unikaty1(i) Then
          tbl(2, idx) = Unikaty2(i) & Chr(10) & tbl(2, idx)
          tbl(4, idx) = Unikaty4(i) & Chr(10) & tbl(4, idx)
        Else
          idx = idx + 1
          tbl(1, idx) = Unikaty1(i)
          tbl(2, idx) = Unikaty2(i)
          tbl(3, idx) = Unikaty3(i)
          tbl(4, idx) = Unikaty4(i)
        End If
      Next
    End With
    
    'i wpisujemy do arkusza
    ileWrs = idx
    idx = 1
    odWiersza = 1   'gdzie rozpoczyna się tabelka wynikowa
    
    With Sheets(3)
      .Cells.ClearContents
      For i = ileWrs + odWiersza - 1 To odWiersza Step -1
        For j = 1 To 4
          .Cells(i, j) = tbl(j, idx)
        Next
        idx = idx + 1
      Next
      .Activate
    End With
    
    Application.ScreenUpdating = True
    End Sub
    


    Dane do tego pliku dostosuj.xls wrzucam z innego pliku, tu np. 2016-02-05.xls
    Z tego pliku kopiuję konkretnie kolumny A, B, G, H.
    Do pliku dostosuj.xls wrzucam je odpowiednio:

    żródło - dostosuj.xls
    A - A
    B - C
    G - B
    H - D

    Sprawa się lekko komplikuje, bo muszę wykorzystać też wartości z pliku źródłowego z kolumny E.

    Chciałbym uzyskać coś takiego:
    żródło - dostosuj.xls
    A - A
    B - D
    E - B
    G - C
    H - E

    Z tym, że wynikowo każdą wartość "DC Teresin FF" w kolumnie C w pliku dostosuj.xls chciałbym mieć zamienioną na wartość z kolumny B z tego samego wiersza.
    Co pozmieniać w makrze aby to wyciągnął?
    Jest to do ogarnięcia?
  • Helpful post
    #35
    marek003
    Level 40  
    Sprawdź czy dobrze - Bo nie wiem czy dobrze zrozumiałem.
    A poprawiałem kod "czysto" matematycznie bez większego rozumienia - minęło 3, roku
    Dane i przycisk dla "nowego" makra w Arkusz2

    Code: vbnet
    Log in, to see the code


    Code: vbnet
    Log in, to see the code

    Code: vbnet
    Log in, to see the code
  • #36
    coobah
    Level 17  
    Marek, dokładnie o to chodziło!
    Super!
    A podpowiedz mi, co usunąć z makra aby rezultat w Arkuszu 3 nie generował kolumny B?
    Jest ona już zbędna...

    Dziękuję bardzo!
  • #37
    marek003
    Level 40  
    Zamiast tej pętli pod koniec kodu:
    Code: vbnet
    Log in, to see the code


    Zastosuj proste przypisanie:

    Code: vbnet
    Log in, to see the code



    Czyli:
    Code: vbnet
    Log in, to see the code


    Sprawdź bo poprawkę robiłem bez excela.
  • #39
    marek003
    Level 40  
    Nie do końca zrozumiałeś kod.

    Poniższy zapis by/jest "wybiegiem" jak się pozbyć w prosty sposób duplikatów jeżeli są.

    Code: vbnet
    Log in, to see the code


    Wiec jego nie trzeba rozbudowywać tylko zaktualizować kolumny.
    A reszta to zwykła "zabawa" na numerach kolumn, czyli
    Code: vbnet
    Log in, to see the code


    Oczywiście jeszcze

    Code: vbnet
    Log in, to see the code


    W załączeniu przykład , ale sprawdź bo ja tez mogę się mylić.
  • #40
    coobah
    Level 17  
    masz rację, nie do końca zrozumiałem kod... :) Przyznaję się bez bicia.

    Twój plik robi robotę, ale jednak te duplikaty występujące przy pojedynczym numerze wysyłki są mi potrzebne....
    Co zmienić, aby zachować te duplikaty? Próbowałem kopiować z mojego pliku wpis zamiast Twojej propozycji:

    Code: vbnet
    Log in, to see the code


    ale nie osiągnąłem tego co chciałem..
  • #41
    marek003
    Level 40  
    Słuchaj ja trochę namieszałem - przyznaje.

    Pierwsze sprawdzanie duplikatów wprowadzone przez kolegę adamasa sprawdzało duplikaty gdy w kolejnym wierszu wystąpił ten sam numerze i i ten sam magazyn.

    Ja stwierdziłem że jeżeli i tak pokazujesz nazwę sklepu (magazyn zastępujesz sklepem) więc poprawiłem kod na sprawdzanie duplikatów po numerze i nazwie sklepu - co jest rzeczywiście błędem bo omija parę danych..

    Proponuje wrócić do "korzeni", czyli linie zastąpić zapisem (chodzi o "4" kolumnę a nie o "5"):

    Code: vbnet
    Log in, to see the code


    lub np by eliminować duplikaty w kolejnym wierszu z tym samym numerem, tym samym magazynem i tym samym czasem dostawy.
    Code: vbnet
    Log in, to see the code


    Ostatecznie można po prostu tą linię "wyłączyć" - daj apostrof przed tą linią - zapis stanie się komentarzem.
    Jednak to miało wcześniej sens (nie po to było wprowadzane) i proponuje tą linię kodu zostawić oczywiście po powyższej modyfikacji wybranej przez ciebie.

    W załączeniu sprawdzanie dubla z ostatnią "opcją" (dubel "z czasem") - myślę że będzie działać tak jak chcesz, a zabezpieczenie przed ewentualnym dublem wiersza zostanie.
  • #42
    coobah
    Level 17  
    Królu Złoty! :)

    Marek, i ta ostateczna wersja jest w 100% tym czego potrzebuję.

    Wszystko śmiga super.
    Serdecznie dziękuję, Twoja wiedza bardzo ułatwi mi działanie.
  • #43
    coobah
    Level 17  
    Jeszcze jeden temat:
    W załączeniu wrzucam plik z makrem i plik z danymi źródłowymi.
    Jak pozmieniać makro, aby z kolumny B w Arkuszu 2 (tam gdzie wrzucam dane źródłowe do przemielenia...) po zapuszczeniu makra w rezultacie otrzymać godzinę wcześniejszą o jedną pełną godzinę? (wiem, masło maślane, ale chyba zrozumiale ;) )
  • #44
    marek003
    Level 40  
    Po pierwsze.
    Jak poszerzasz dane to pamiętaj o poszerzeniu sortowania (do kolumny G):

    Code: vbnet
    Log in, to see the code


    Po drugie
    nie powiela się tych samych deklaracji i jeżeli już pętla w pętli to o jak najmniejszym zakresie działania bo to wydłuża czas pracy makra.

    Najlepiej jednak skorzystać z innych rozwiązań - przecież byłeś blisko.
    Po co sprawdzać każdą cyfrę(pozycję na której występuje "kod") oddzielnie - nie lepiej wprowadzić warunek ">0" i zrezygnować z pętli.

    Chyba że:
    1. "kod" może wystąpić dwa razy i wtedy też ma się pojawić dwa razy "zwrot..."
    2. "Kod" może pojawić się po 10 znaku i wtedy jest "nieważny"

    Poniżej wersja 2 ale bez pętli (wycinam fragment tekstu - 11 znaków dlatego że kod jest dwuliterowy a sprawdzałeś pętlą do 10 miejsca wystąpienia kodu więc ... ) ale jeżeli jest to nieważne to też dla szybkości kodu należy z tego zrezygnować.

    Dołożyłem też tą godzinę "minus"


    Code: vbnet
    Log in, to see the code
  • #45
    coobah
    Level 17  
    Marek, dzięki za odpowiedź.
    Nie ukrywam, że mam już działające makro. Trochę inaczej opisane niż Ty to zrobiłeś, ale działa.

    Przetestowałem Twój kod i tradycyjnie już - wszystko jest OK :)
  • #46
    coobah
    Level 17  
    Jako, że apetyt rośnie w miarę jedzenia, albo: daj palca a wezmą całą rękę, podbijam temat i proszę o pomoc :)

    Jako, że wszystko działa to zawsze znajdzie się coś co może być potrzebne :)

    Mam plik z makrem, mam plik źródłowy.
    W pliku źródłowym jest jeszcze kolumna E "Numer Sklepu".
    Numer Sklepu jest zawsze stały dla konkretnej Nazwy Sklepu, np 31073 to zawsze będzie Stalowa Wola.

    A teraz o co chodzi.
    Wynikowo makro sortuje nazwy sklepów chronologicznie do Czasu Dostawy.
    Zależy mi aby to samo robiło z Numerami Sklepów.

    Czyli np tak:

    Excel - Tworzenie makra - sortowanie i przenoszenie między komórkami

    Jeśli mogę powybrzydzać to chciałbym, aby z tej kolumny Numer Sklepu nie były brane pod uwagę dwie wartości: 39004 i 39002.

    Pomożecie?
  • #48
    marek003
    Level 40  
    :) A Ty nie możesz usiąść raz na pupie pomyśleć "raz z tej raz z drugiej" strony co tak naprawdę chce. Co chwila zmieniasz zeznania - zaczyna być to monotonne.

    Sprawdź rozwiązanie bo robiłem to automatycznie poprzez dodanie kolumny i skorygowanie kodu o 1. Nie analizowałem wszystkiego czy jest poprawnie.
  • #49
    coobah
    Level 17  
    Marek, tak jak napisałem: daj palca, a weźmie całą rękę :)
    Jak ciągłe zmienianie zdania może być monotonne? Chyba właśnie na odwrót powinno to być odbierane :)

    A rozwiązanie eleganckie, superowe, wyśmienite.
    "Działa jak natura chciała" :)

    A tak poważnie: bardzo dziękuję, jest to o czym myślałem.