Wątek przeniesiony 2021-09-16 09:56 z Inne języki programowania przez cerrato.

VBA problem z tablicami

0

Witam,

Proszę o pomoc/poradę przy takim problemie :

Utworzyłem mały skrypt, który ma za zadanie ułatwić mi pracę w arkuszu kalk. Jego działanie polega na tym :

przypisuję do tablica(1) wartość z komórki (124,7), następnie w pętli dla i =1 do 31 dla 31 wierszy wykonuję takie działanie : zaznaczam komórkę (84+i,7) i przypisuję jej wartość do tablicy pakiet, następnie usuwam jej wartość i automatycznie zmienia mi się wartość w komórce (124,7) i tę wartość przypisuję do tablica(i+1) i sprawdzam warunek : jeżeli wartość z tablica(i+1) jest większa od najmniejszej wartość z tej tablicy (utworzyłem funkcję MinTablicy, która ma w każdej kolejnej pętli sprawdzać zawartość tablicy i znajdować jej wartość najmniejszą), wtedy z powrotem przypisuje usuniętą wartość do komórki (84+i,7), która wcześniej została zapamiętana w tablicy pakiet. Jeżeli warunek jest negatywny, usuwa wartość z komórki (84+i,7) i pozostawia komórkę wolną. Problem polega na tym, że w wyniku działania skryptu w poszczególnych wierszach kolumny 7 skrypt nie przypisuje wartości do komórek z warunku if-else.


Function MinTablicy(Tablica As Variant) As Variant

    Dim WartMin As Double
    
    Dim IndeksDolny As Long, IndeksGorny As Long, j As Long
    
    IndeksDolny = LBound(Tablica)
    
    IndeksGorny = UBound(Tablica)
    
    WartMin = Tablica(IndeksDolny)
    
    For j = IndeksDolny To IndeksGorny
    
      If Tablica(j) < WartMin Then WartMin = Tablica(j)
      
    Next
    
    MinTablicy = WartMin
    
End Function


Sub optymalizacja()

Dim i As Integer
Dim Tablica(32) As Variant
Dim pakiet(31) As Variant
Dim min As Double


Erase Tablica
Erase pakiet

Tablica(1) = Cells(124, 7).Value


    For i = 1 To 31
    
    
        pakiet(i) = Cells(84 + i, 7).Value
  
        Cells(84 + i, 7).Select
        Selection.ClearContents
        
        Tablica(i + 1) = Cells(124, 7).Value
        
            min = 0
        
            min = MinTablicy(Tablica)
           
             If Tablica(i + 1) > min Then
        
               Cells(84 + i, 7).Value = pakiet(i)
               
               
             Else
                
                Cells(84 + i, 7).Select
                Selection.ClearContents
    
             End If
                                    
             
         Cells(128 + i, 7) = Tablica(i)
         Cells(128 + i, 8) = min
         
        
     Next i
        
End Sub

0

Fajny skrypcik - zaraz go przeanalizuję.
Przed chwilą odpaliłem skrypt. Do komórki (124,7) wpisałem wartość 45. W komórkach od (84-115,7) wpisałem losowe numery. Skrypt za każdym razem wchodzi do pierwszego if bo zawsze (45 > 0) czyli ponownie przepisuję zawartość komórek *(84-115,7) do komórek * (84-115,7).

W komórkach (129-159,7) skrypt wstawia wartość 45 bo taka jest zawartość wszystkich komórek tablicy Tablica.

Przejrzyj sobie ten skrypt jeszcze raz z użyciem funkcji msgbox. Wstaw msgbox w kodzie i sprawdzaj co się dzieje. W pracy piszę mnóstwo takich skryptów i jak coś nie działa to sprawdzam msgboxem.

0
czajkovico napisał(a):

Witam,
Utworzyłem mały skrypt, który ma za zadanie ułatwić mi pracę w arkuszu kalk. Jego działanie polega na tym :

  • następnie usuwam jej wartość i automatycznie zmienia mi się wartość w komórce (124,7)** i tę wartość przypisuję do tablica(i+1)


Dlaczego uważasz że coś ci się automatycznie zmienia w komórce (124,7)? Z tego co widzę to ty wcale nie zmieniasz zawartości komórki (124,7) gdziekolwiek...
0
 
Cells(84 + i, 7).Select
Selection.ClearContents

Nie możesz zakładać że po wykonaniu tych instrukcji skrypt zauważy zmianę wartości w (124,7) na podstawię powiązań z innymi obliczeniami... - wydaję mi się że to tak nie działa....Może by to i zadziałało gdybyś użył obsługi zdarzeń.

 
        Tablica(i + 1) = Cells(124, 7).Value

Tablica(i+1) - ma cały czas tą samą wartość podczas wykonywania skryptu. Wpisz sobie:

 
MsgBox (Cells(124, 7).Value)

po instrukcji Selection.ClearContents

0

Dołączyłem zrzuty z działania programu jaki chciałbym uzyskać, mianowicie :
zrzut_1 : Początek działania programu. Mamy wartości w komórkach od G85 do G115 i zmienną zmieniającą swą wartość w zależności od manipulacji komórkami z wyżej wymienianego przedziału znajdującą się w komórce G124.
Zaczynamy : Usuwam wartość z komórki G85 i analizuję czy wartość w komórce G124 się zwiększyła czy zmniejszyła (zrzut_2) - w tym przypadku się zwiększyła więc nie mogę usunąc zawartości komórki G85 i muszę przywrócić jej poprzednią wartość.
Przechodzę do komórki G86 i robię to samo - usuwam jej zawartość i patrzę, czy wartość w G124 się zwiększa/zmniejsza. W tym przypadku się zmniejsza więc jest ok - zostawiam komórkę G86 pustą. Przechodzę do komórki G87 i robię znów to samo - usuwam jej zawartość i analizuję, czy i tym razem usunięcie wartości komórki G87 powoduję , ze wartość komórki G124 maleje czy rośnie w stosunku do poprzedniej jej wartości. W tym przypadku wartość jest większa więc nie mogę usunąć wartości z komórki G87.
Przechodzę do komórki G88...89 itd i każdorazowo sprawdzam jak sie zmienia wartość komórki G124 kiedy usuwam wartość z komórek do G115. Muszę uzyskąć jak najmniejszą wartość w komórce G124 usuwając lub nie komórki z zakresu G85do115.

Mam nadzieję, ze logicznie to przedstawiłem :)

0
czajkovico napisał(a):

Usuwam wartość z komórki G85 i analizuję czy wartość w komórce G124 się zwiększyła czy zmniejszyła....

W skrypcie tego nigdzie nie analizujesz bo podczas wykonywania tego skryptu komórka 124 ma cały czas tą samą wartość. Być może ta wartość się zmienia podczas usuwania w.w komórek w trakcie pracy z Excelem ale skrypt tego nie widzi w czasie swojego działania...

0

Po uruchomieniu mojego makra uzyskuję taki oto wynik jego działania jak na dołączonym PRT SC 6. Heh efekt jest tak jakby prawidłowy. w Kolumnie G od wiersza 85 do 115 pozostały tylko 2 wartości, które należałoby usunąć aby otrzymać najmniejszą wartość w komórce G124.
Moim zamierzanym efektem było uzyskanie takiego efektu jak na PRT SC 7. Efekt jest tak jakby odwrotny. Uzyskuję adresy komórek, które muszę usunąć aby otrzymać najmniejsza wartość w G124. Dziwne :)

0

Ustaw się w dowolnej linijce makra i naciśnij klawisz F9 - to ustawi brakpoint. Po tym naciśnij klawisz F5(debug) - gdy to wykonasz możesz poruszać się po programie za pomocą klawisza F8 - jak najedziesz na aktualnie analizowaną linijkę kursorem myszy to zobaczysz wartość danej zmiennej. W ten sposób możesz prześledzić sobie działanie makra w czasie jego działania - na żywo!.
www.voila.pl/075/imkjk/index.php?get=1&f=1
www.voila.pl/073/uobba/index.php?get=1&f=1

1

Tablice w VB są indeksowane od zera a stosując UBound(Tablica) wychodzisz poza tabele. Powinno być Ubound(Tablica) - 1

Funkcje min napisałbym tak( dodatkowy parametr):

 
Function MinTablicy(Tablica As Variant, maxInd As Integer) As Variant 'tu zmiana'
 
    Dim WartMin As Double
 
    Dim IndeksDolny As Long, IndeksGorny As Long, j As Long
 
    IndeksDolny = LBound(Tablica)
 
    IndeksGorny = UBound(Tablica)
 
    WartMin = Tablica(IndeksDolny)
 
    For j = IndeksDolny To maxInd 'tu zmiana'
 
      If Tablica(j) < WartMin Then WartMin = Tablica(j)
 
    Next
 
    MinTablicy = WartMin
 
End Function

no i wywołanie:

min = MinTablicy(Tablica, i + 1) 'tu zmiana'
 

No i musisz pozmieniać odwołania do tablicy - jak chcesz się dostać do pierwszego elementu tablicy to piszesz Tablica(0) a nie Tablica(1).

0

DATAMINING WISZĘ CI PIWO !!!! :) WIELKIE DZIĘKI ZA POMOC ! Nie zwróciłem uwagi, że indeksowanie tablic zaczyna się od 0 !

1 użytkowników online, w tym zalogowanych: 0, gości: 1