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

Problem z makrem Excel

+1 głos
134 wizyt
pytanie zadane 6 listopada 2021 w Visual Basic przez Quba Użytkownik (790 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 (18,850 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 (790 p.)

Dziękuję bardzo za pomoc smiley

0 głosów
odpowiedź 11 listopada 2021 przez VBService Ekspert (203,050 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 (790 p.)

Dziękuję bardzo za pomoc smiley

 

Podobne pytania

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

89,693 zapytań

138,297 odpowiedzi

309,243 komentarzy

59,623 pasjonatów

Motyw:

Akcja Pajacyk

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

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...