• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z makrem Excel

VPS Starter Arubacloud
+1 głos
346 wizyt
pytanie zadane 6 listopada 2021 w Visual Basic przez Quba Użytkownik (870 p.)

Witam

Mam problem z poniższym makrem w Excelu. Mianowicie potrzebuję aby Excel wyświetlił wynik związany z dniami, w których wybrana osoba nie wydała pieniędzy. Tak wygląda napisane przeze mnie makro.

Function kiedy_robil_zakupy(kto_dany As String) As String

Dim k As Date, data As Range, d, n As String, kto As Range, kk, z As Integer
Set data = [f4:f22]
Set kto = [c4:c22]
kk = 0
n = ""

For k = "02-1" To "02-27"

    kk = kk + 1
    d = Right(data(kk), 2)
    If kto(kk) <> kto_dany And InStr(n, d) = 0 Then n = n & ", " & d

Next k

z = Len(n)
kiedy_robil_zakupy = Right(n, z - 2)

End Function

A tak wygląda tabela, na której działam

Chcę aby kod wyrzucił mi dni, w których dla argumentu Adam pokaże mi dni, w których Adam nie wydawał pieniędzy. Natomiast wynik jaki wyrzuca kod to:

03, 06, 09, 15, 18, 21, 22, 24, 26, 27

Jak widać powyżej nie jest to do końca poprawne gdyż pojawia się liczba 24. A jak widać w tabeli 24-02 Adam wydał pieniądze. Nie mogę znaleźć błędu w kodzie powyżej i będę bardzo wdzięczny za wszelką pomoc, gdyż zmagam się z tym zadaniem od kilku godzin.

Pozdrawiam

2 odpowiedzi

0 głosów
odpowiedź 7 listopada 2021 przez overcq Pasjonat (21,540 p.)
wybrane 8 listopada 2021 przez Quba
 
Najlepsza

Najpierw należy utworzyć listę, kiedy zrobił zakupy, grupując według dni, a następnie przeciwstawną listę czyli w których dniach nie zrobił zakupów.

Function kiedy_robil_zakupy(kto_dany As String) As String
    Dim data As Range, d, n(), m(), i As Integer, kto As Range, k As Integer, z As Integer, s As String, f As Boolean, l As Integer
    Set data = [d1:d19]
    Set kto = [a1:a19]
    i = 0
    prev_d = Right(data(1), 2)
    kto_zrobil = False
    For k = 1 To 19 'liczba wierszy
        d = Right(data(k), 2)
        If prev_d <> d And kto_zrobil Then
            i = i + 1
            ReDim Preserve n(i)
            n(i) = Int(prev_d)
            kto_zrobil = False
        End If
        If Not kto_zrobil And kto(k) = kto_dany Then kto_zrobil = True
        prev_d = d
    Next
    If kto_zrobil Then
        i = i + 1
        ReDim Preserve n(i)
        n(i) = Int(d)
    End If
    l = 0
    For j = 1 To 27 'liczba dni w miesiącu
        f = False
        For k = 1 To i
            If n(k) = j Then
                f = True
                Exit For
            End If
        Next
        If Not f Then
            l = l + 1
            ReDim Preserve m(l)
            m(l) = j
        End If
    Next
    s = ""
    For j = 1 To l
        s = s & ", " & m(j)
    Next
    z = Len(s)
    If s <> "" Then
        kiedy_robil_zakupy = Right(s, z - 2)
    Else
        kiedy_robil_zakupy = ""
    End If
End Function
Sub test()
    MsgBox (kiedy_robil_zakupy("Adam"))
End Sub

 

komentarz 8 listopada 2021 przez Quba Użytkownik (870 p.)

Dziękuję bardzo za pomoc smiley

0 głosów
odpowiedź 11 listopada 2021 przez VBService Ekspert (251,270 p.)
edycja 11 listopada 2021 przez VBService

Proponuję za pomocą jednej pętli bez tworzenia list

Function kiedy_robil_zakupy(kto_dany As String) As String
    Dim r_data As Range
    Dim return_value, skip_value, current_value, last_value, last_row As String
    
    last_row = CStr(Cells(Rows.Count, 3).End(xlUp).Row)
    last_value = vbNullString
    skip_value = vbNullString
 
    For Each r_data In Range("F4:F" & last_row)
        current_value = CStr(Day(r_data.value))
    
        If Cells(r_data.Row, 3).value = kto_dany Then
            skip_value = current_value
        End If
        
        If Not Cells(r_data.Row, 3).value = kto_dany _
           And Not skip_value = current_value _
           And Not last_value = current_value Then
            last_value = current_value
            return_value = return_value & current_value & " "
        End If
        
        If Not InStr(1, return_value, skip_value) = 0 Then
            return_value = Replace(return_value, skip_value, vbNullString)
            return_value = Replace(return_value, "  ", " ")
        End If
    Next
    
    kiedy_robil_zakupy = Replace(Trim(return_value), " ", ", ")
End Function

i bez ustawiania na "sztywno"

Set data = [f4:f22]
Set kto = [c4:c22]
 
For k = "02-1" To "02-27"

 

komentarz 16 listopada 2021 przez Quba Użytkownik (870 p.)

Dziękuję bardzo za pomoc smiley

 

Podobne pytania

0 głosów
0 odpowiedzi 357 wizyt
pytanie zadane 20 stycznia 2021 w Visual Basic przez Koner Nowicjusz (120 p.)
0 głosów
0 odpowiedzi 141 wizyt
pytanie zadane 13 marca 2018 w Visual Basic przez MR.X Użytkownik (860 p.)
0 głosów
1 odpowiedź 186 wizyt
pytanie zadane 1 września 2022 w Visual Basic przez morking Nowicjusz (210 p.)

92,455 zapytań

141,263 odpowiedzi

319,100 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...