Supportnet Computer
Planet of Tech

Supportnet / Forum / Tabellenkalkulation

Makro in Excel zum zählen von Werten





Frage

Hallo habe heute mein erstes Makro geschrieben. Nun bekomme ich diverse Fehlermeldungen. Kann mir einer sagen was falsch daran ist? Was will ich bewirken? Ich möchte aus einer Spalte Werte zählen. Bsp: Sonne Mond Sterne Sonne Sterne ... Die Anzahl der möglichen String-Variationen ist offen. Die zu vergleichenden Zeilen sollen später entweder durch Eingabe oder durch Excel selbst (wenn sie leer sind ganz unten) bemerkt werden. Das Script soll nun zählen wie oft Sonne, Mond oder Sterne in der Spalte auftreten und dieses Ergebnis in Spalte B und C präsentieren. (ist noch nicht ganz fertig das Script ) also: Sonne 2 Mond 1 Sterne 2 Hier das Script: [code]Public Sub Werte_zählen() Dim ncounter As Integer Dim Wert As String Dim i As Integer Dim a As Integer ReDim Vektor(i) As Integer ReDim count(i) As Integer i = 1 For ncounter = 1 To 25 rem (die 25 wird später mal Variable oder Eingabe) a = i Wert = Cells(ncounter, 1).Value If Vektor(i) <> Wert Then rem ( in dieser Zeile, if vektor(i) ... kommt Fehlermeldung, siehe unten) If i > 1 Then i = i - 1 Else i = a Vektor(i) = Wert End If Else count(i) = count(i) + 1 End If i = a + 1 Next ncounter For i = 1 To a Cells(i, 2).Value = Vektor(i) i = i + 1 Next i End Sub [/code] * An dieser Stelle kommt die Fehlermeldung : "Laufzeitfehler ´9´ Index außerhalb des gültigen Bereichs" Kann wer helfen? Gruß SkunK

Antwort 1 von Karlchen

Die Fehlermeldung erhältst Du, weil das Feld Vektor nur 1 Element enthält. Auf dieses kannst Du nur mit dem Index 0 zugreifen. i hat aber zum Zeitpunkt der Fehlermeldung schon den Wert 1 und versucht daher auf ein Element zuzugreifen, welches nicht existiert.

Wenn Du diesen Fehler beseitigst wird ein neuer auftreten.
Zitat:
If Vektor(i) <> Wert Then

Vergleicht einen Integer-Wert mit einem String. Du kannst nur gleiche Datentypen miteinander vergleichen.

leider habe ich im Moment keine Zeit, sonst würde ich Dir das Makro schreiben, aber ich hoffe, ich konnte weiterhelfen.

nicht den Mut verlieren
Karlchen

Antwort 2 von Saarbauer

Hallo,

der Fehler liegt nicht in der Zeile sonder in den Zeilen davor. "Vektor" ist "Integer" und "Wert" "String" Ausserdem wird der Wert "i" erst nach der ersten Verwendung gesetzt.

nach meiner Meinung sind auch die beiden Funktionen

"ReDim Vektor(i) As String
ReDim Count(i) As Integer"

an der falschen Stelle.
Es sind nach meiner Meinung noch weitere Fehler drin. aber da guckst du vielleicht selber , da ich nicht genau weß was du vorhast.

Gruß

Helmut

Antwort 3 von Skunk

hmm,, danke erst mal für eure antworten, aber das mit dem Array versteh ich anscheind nicht ganz. Das mit dem "ReDim Vektor(i) As Integer" hat ich nur zu testzwecken mit zahlen.
Aber wie meint ihr das, dass i am anfang null hat oder so?

Was ich erreichen will ist, eine Variable mit x möglichen "Speicherfeldern" also zB Vector(20), kann 20 Zahlen bzw. Werte beeinhalten.
zB. Vector(1) = Sonne, Vector(2) = Mond, Vector(i) = xxx
Daher will ich eine Variable bzw. einen Vektor, der i - verschiedene Strings speichern kann. Oder muss ich vorher die Größe des Vectors angeben also

ReDim Vektor(100) As String 


um dann später in der Berechnung Vektor(i) für 0 <= i <=100 die Speicherfelder nutzen zu können?

Antwort 4 von cmkatz

Hi,
hab hier mal was gebastelt. Einziger Makel: in Spalte B wird noch einma die ganze Werteliste der Spalte A aufgeführt.
Hab das noch nicht wirklich hinbekommen...

Aber ein Anfang ist es! ;-)

Also hier der Code:


Public Sub Werte_zählen()
    Dim ncounter As Integer
   
    Dim i As Integer
    Dim a As Integer
    Dim y As Integer
    ReDim Vektor(1 To 500) As String
    ReDim Count(1 To 500) As Integer
    Dim ZelleLeer As Boolean
    Dim written As Boolean
    
    ´ Vektor füllen:
    ´=============================
    ZelleLeer = False
    i = 0
    Do Until ZelleLeer = True
        i = i + 1
        Vektor(i) = Cells(i, 1).Value
        If Cells(i + 1, 1).Value = "" Then
         ZelleLeer = True
        End If
        
    Loop
    
    
    
    ´Counter füllen:
    ´=============================
    For a = 1 To i
        y = 1
        For ncounter = 1 To i
            If Vektor(a) = Cells(ncounter, 1).Value Then
                Count(a) = y
                y = y + 1
            Else
                Count(a) = Count(a)
          End If
        Next ncounter
    Next a
    
    ´Spalten B und C mit Vektoren fuellen:
    ´==============================
    For a = 1 To i
        Cells(a, 2).Value = Vektor(a)
        Cells(a, 3).Value = Count(a)
    Next a
    
End Sub


Gruß
cmkatz

Antwort 5 von Saarbauer

Hallo,

wenn du die Funktion

ReDim

so anordnest, dass sie erhöht wird wenn ein neuer wert kommt hast du das erreicht was du willst..

du kannst i mit in Prinzip mit null anfangen lassen, aber

ReDim Vektor( i) As Integer
ReDim count( i) As Integer

könnte Schwierigkeiten bereiten.

Gruß

Helmut

Antwort 6 von Skunk

danke danke Leute ihr seid echt spitze ;)

allerdings hab ichs schon selbst fast geknackt.

ok. also cmkatz, dein Code sehr gut, hab in der zeit auch noch´n bissl rum gespielt. Hat eigentlich geklappt. er gab mir die Werte aus. Allerdings immer nur den ersten. Denk ma, dass da ein i oder a falsch läuft und nur i=1 ausgegeben wird. letzte schleife vermutlich.

Dein Code nutzt einen Trick nicht aus, weshalb er alle (im maximalen Fall) 500 Stringsätze ausgibt.
Ich möchte aber, dass er nur die Strings anzeigt die unterschiedlich sind. d.h. ich erklärs nochma

Folgender Excel-Datensatz

Sonne
Mond
Sonne



Angenommen er ist beim dritten ncounter Durchlauf. Nun wird a = i (also 3) gesetzt. Jetzt wird der Wert in Zeile 3 ausgelesen Wert = "Sterne". Nun kommt er in die Schleife wo Vektor(i) mit i=3 mit dem Wert ("Sterne") verglichen wird. Vektor(3) besitzt allerdings noch keinen Wert und gibt ein TRUE weiter (Leeres Feld ist ungleich Wert("Sterne")). Daher springt er in die nächste Schleife wo überprüft wird ob i noch größer als 1 ist. Mit i=3 gibts TRUE zieht vom i eins ab i = 3 - 1 = 2 und verläßt die schleife. Nun wird der Vektor(i) mit i=2 überprüft. d.h. er vergleicht 2Sonne" mit "Mond" bekommt TRUE , gleiche Prozedur wie eben und zieht wieder eins ab i=1. Nun wird wieder getestet Vector(1) mit Wert also "Sonne" mit "Sonne". Das gibt FALSE weil is ja nicht ungleich. daher wird mit zu diesem count(1) eins dazugezählt und Count(1) = 2, also 2x die Sonne.

bis ncounter abgelaufen ist immer so weiter.

Die Ausgabe is ja dann klar. i wird wieder eins gesetzt und läuft bis a (maximale i Zahl, also bei dem Beispiel nur 2) und gibt dann
 Cells(1,2).Value = Veltor(1)
und
 Cells(1,3).Value = Count(1) 
usw.

Der VOrteil dabei, es werden nur die Felder mit Counts angezeigt, die im Vektor i einmalig enthalten sind.

Aber wieso bekomm ich jetzt nur die erste Zeile angezeigt?
Hier nochmal mein neuer code zum testen.

rem =========== Code ==========

Public Sub Werte_zaehlen()


Dim ncounter As Integer
Dim Wert As String

Dim i As Integer
Dim a As Integer
ReDim Vektor(100) As String
ReDim Count(100) As Integer

i = 1

For ncounter = 1 To 4

Rem (die 25 wird später mal Variable oder Eingabe)

a = i


Wert = Cells(ncounter, 1).Value

If Vektor(i) <> Wert Then


If i > 1 Then

i = i - 1

Else

i = a

Vektor(i) = Wert

End If

Else

Count(i) = Count(i) + 1

End If

i = a + 1

Next ncounter

For i = 1 To a

Cells(i, 2).Value = Vektor(i)
Cells(i, 3).Value = Count(i)
i = i + 1

Next i

End Sub

========= Code Ende ============

danke für eure Hilfe !

gruß Skunk

Antwort 7 von Skunk

ok.. bin einen schritt weiter .. nur kommt wieder n blöder Fehler. Kann das an den While Do SChleifen liegen? Sind die richtig?

Fehlermeldung bei Vektor(i) = Wert (gelb markiert)
"Laufzeitfehler=´9´:
Index außerhalb des gültigen Bereichs"


Public Sub Werte_zaehlen()


Dim ncounter As Integer

Dim Wert As String


Dim i As Integer

Dim a As Integer

Dim b As Integer


ReDim Vektor(100) As String
ReDim Count(100) As Integer

i = 1
b = 1

   For ncounter = 1 To 4
Rem (die 25 wird später mal Variable oder Eingabe)

   a = i
   Wert = Cells(ncounter, 1).Value
         While Vektor(i) <> Wert
          Do
            If i > 1 Then
                i = i - 1
            Else
                  i = b
                  Vektor(i) = Wert
                  b = b + 1
         End If
       Count(i) = Count(i) + 1
      Loop

      Wend

      i = a + 1
   Next ncounter

         i = 1
          While i <= b
         Do
            Cells(i, 2).Value = Vektor(i)
            Cells(i, 3).Value = Count(i)
             i = i + 1
         Loop
      Wend
End Sub


gruß Skunk

Antwort 8 von SoSollsSein

Dieser Code sollte funktionieren.

ganz wichtig, der Teil mit dem Type muss vor der Sub stehen


Type NameCount
Name As String
Count As Integer
End Type

Public Sub Werte_zaehlen()

Dim ncounter As Integer
Dim Wert As String
´Flag, ob der Eintrag in der Liste gefunden wurde
Dim found As Boolean
Dim i As Integer

´gibt die aktuelle Länge der Liste an
Dim Anzahl As Integer

´Länge der Liste ist noch unbestimmt
Dim Liste() As NameCount

found = False
For ncounter = 1 To 4
Wert = Cells(ncounter, 1).Value

´Test, ob überhaupt etwas in der Zelle stand
If Wert <> "" Then
For i = 1 To Anzahl
´vergleicht Wert mit Name aus Liste
If Liste(i).Name Like Wert Then
´wenn gleich, dann wird der Counter des Elementes erhöht
Liste(i).Count = Liste(i).Count + 1
´Flag wird gesetzt
found = True
´Abbruch der For-Schleife
Exit For
End If
Next i
´wenn nicht gefunden, dann muß die Liste verlängert werden
If found = False Then
Anzahl = Anzahl + 1
´passt Länge der Liste an, ohne die bisherigen Werte zu löschen
ReDim Preserve Liste(Anzahl)
Liste(Anzahl).Name = Wert
Liste(Anzahl).Count = 1
End If
found = False
End If
Next ncounter

´Ausgabe des Ergebnisses
For i = 1 To Anzahl
Cells(i, 2).Value = Liste(i).Name
Cells(i, 3).Value = Liste(i).Count
Next i

End Sub

Gruß
Pete

Antwort 9 von Event

Hallo

hier mein kurzer Vorschlag:

Private Sub CommandButton1_Click()
Dim c As Object, i As Long
Range("A1:" & Range("A65535").End(xlUp).Address).Select
For Each c In Selection
If c.Value <> "" Then i = i + 1: Names.Add Name:=c.Value, RefersTo:="$b$" & CStr(i)
Next c
i = 2 ´beginne in Zeile 2
For Each c In ActiveSheet.Names
Cells(i, 2) = Right(c.Name, Len(c.Name) - InStr(c.Name, "!"))
Cells(i, 3).FormulaLocal = "=Zählenwenn(" & Selection.Address & " ; B" & CStr(i) & ")"
i = i + 1
Next c
End Sub

Gruß

Ich möchte kostenlos eine Frage an die Mitglieder stellen:


Ähnliche Themen:


Suche in allen vorhandenen Beiträgen: