Težava pri iskanju vrednosti v celicah

Pomoč pri izdelavi makrov
Odgovori
capirossi
Prispevkov: 25
Pridružen: Če Dec 10, 2009 12:51 pm

Težava pri iskanju vrednosti v celicah

Odgovor Napisal/-a capirossi »

V celicah BN3 do BN750 (sprememba vrednosti), BI3 do BI750 (datum+ura), BF3 do BF750 (vrednost) imam vpisane vrednosti(vse vrednosti so izračuni). V celico AR40 vpišem formulo =MAX(BN3:BN750), v celico AR41 pa formulo =MIN(BN3:BN750). Potem pa želim, da mi program izpolni naslednjo tabelo:

.........AR....AS......AT........AU..........AV........AW.........AX........AY.......AZ
38............................................................................podatki
39................................................ura-2...ura-1.....ura.....ura+1....ura+2
40....MAX.......at..........datum+ura
41....MIN........at..........datum+ura
42
43

V celico AU40 želim zapisati datum+uro najvišje spremembe, v celice od AV40 do AZ40 pa vrednosti iz celice BF.
V celico AU41 pa želim zapisati datum+uro najnižje spremembe, v celice od AV41 do AZ41 pa vrednosti iz celice BF. Če pa imam več enakih najnižjih vrednosti pa jih zapišem v celice AU42, AU43,...
Trenutno sem za to nalogo uporabil naslednjo kodo:

Koda: Izberi vse

Dim konec_na_listu As Long
Dim zadetki As Integer
zadetki = 0
konec_na_listu = Range("BN65536").End(xlUp).Row
  For iscimax = 1 To konec_na_listu
      If (Range("AR40") = Range("BN" & iscimax)) Then
            Range("AX40") = Range("BF" & iscimax)
            Range("AV40") = Range("BF" & iscimax - 2)
            Range("AW40") = Range("BF" & iscimax - 1)
            Range("AY40") = Range("BF" & iscimax + 1)
            Range("AZ40") = Range("BF" & iscimax + 2)
            Range("AU40") = Range("BI" & iscimax)
       End If
  Next
    
  For iscimin = 1 To konec_na_listu
       If (Range("AR41") = Range("BN" & iscimin)) Then
           Range("AX" & zadetki + 41) = Range("BF" & iscimin)
           Range("AV" & zadetki + 41) = Range("BF" & iscimin - 2)
           Range("AW" & zadetki + 41) = Range("BF" & iscimin - 1)
           Range("AY" & zadetki + 41) = Range("BF" & iscimin + 1)
           Range("AZ" & zadetki + 41) = Range("BF" & iscimin + 2)
           Range("AU" & zadetki + 41) = Range("BI" & iscimin)
           zadetki = zadetki + 1
      End If
  Next
Po zagonu kode pa sem ugotovil, da ne najde vseh zadetkov, ki bi jih morala. Npr. najvišja vrednosti je bila 1,8, ki jo je program pravilno našel in v tabelo pravilno izpisal želene vrednosti, problem pa se je pojavil pri najnižji vrednosti. Najnižja vrednost je bila -0,2 in je bila v celicah od BN3 do BN750 vpisana 20x ali več kljub temu pa mi jo je v tabelo vpisalo samo 16x. Potem sem z naslednjo kodo preveril koliko zadetkov je dejansko našlo in rezultat je bil 16:

Koda: Izberi vse

For stej = 3 To 5000
    If (Range("AR41") = Range("BN" & stej)) Then
        test = test + 1
    End If
    Next
Range("AU31") = test
Kje sem ga polomil?

Že v naprej se vam zahvaljujem za odgovor.

Lep pozdrav, Loris
admin
Site Admin
Prispevkov: 3687
Pridružen: Sr Jul 20, 2005 10:06 pm

Odgovor Napisal/-a admin »

Seveda nisem šel vsega tega pisat in preizkušat in na srečo ste priložili še "testno" kodo in s tem sem dojel, kaj vas muči. Mislim da vam vse deluje OK oz pravilno. Program vam pravilno najde neko najmanjšo vrednost - recimo 0,199987, vi pa imate nastavljen pogled na recimo dve decimalki in vidite 0,20:

Koda: Izberi vse

Originalna vred.   Kaj vidite pri dveh decimalkah
       0,199987       0,20
       0,196557       0,20
       0,196862       0,20
       0,195421       0,20
       0,193961       0,19
       0,19301        0,19
       0,195793       0,20
       0,193966       0,19
       0,198717       0,20
       0,195338       0,20
       0,199961       0,20
In če gledate bi lahko rekli, da imate 8 minimalnih vrednosti, a jaz vidim le eno (0.193010).
lp,
Matjaž Prtenjak
Administrator
capirossi
Prispevkov: 25
Pridružen: Če Dec 10, 2009 12:51 pm

Odgovor Napisal/-a capirossi »

Tudi če nastavim vse celice na prikaz 5 decimalk mi prikaže številke -0,2000 , 1,2000 , -0,1000 pa tudi program iz katerega kopiram vrednosti v excel mi zapisuje vrednosti na 1 decimalko natančno, torej bi morala biti tukaj druga napaka.
Imate še kakšno rešitev? Je mogoče to povezano s tem, da mi vrednosti v celicah izračuna?

Lep pozdrav, Loris
admin
Site Admin
Prispevkov: 3687
Pridružen: Sr Jul 20, 2005 10:06 pm

Odgovor Napisal/-a admin »

Da; zagotovo je to kar sem vam opisal. Stvar je namreč v tem, da v računalništvu nikoli ne smete primerjati dveh realnih števili na enakost, ker računalnik nima neomejene natančnosti in prihaja do napak. Rešitvi sta dve.
  1. SLABŠA: Pred primerjenjem vrednosti zaokrožite na isto število decimalk in števili nato primerjajte
  2. BOLJŠA: Določite neko toleranco - to je v matematiki znano kot epsilon - in potem rečete, da sta števili enaki, če sta narazen za manj kot ta epsilon:

    Koda: Izberi vse

    Sub test()
      Dim st1 As Double: st1 = 123.456789
      Dim st2 As Double: st2 = 123.456799
      
      If (st1 = st2) Then
        Debug.Print "1) Števili sta enaki"
      End If
      
      Dim epsilon As Double: epsilon = 0.0001
      If (Abs(st1 - st2) < epsilon) Then
        Debug.Print "2) Števili sta enaki"
      End If
    End Sub
    
lp,
Matjaž Prtenjak
Administrator
capirossi
Prispevkov: 25
Pridružen: Če Dec 10, 2009 12:51 pm

Odgovor Napisal/-a capirossi »

Sem uporabil drugo rešitev in stvar dela tako kot mora.
Najlepša hvala za hitro pomoč.

Lep pozdrav, Loris
Odgovori