Office: VBA Schleife zu umständlich, Wie gehts besser?

Helfe beim Thema VBA Schleife zu umständlich, Wie gehts besser? in Microsoft Excel Hilfe um das Problem gemeinsam zu lösen; Hallo,<O:p></O:p> ich habe eine Frage zu einer Schleife in VBA. Ich habe einen Code geschrieben in der verschiedene Schleifen abgearbeitet werden.... Dieses Thema im Forum "Microsoft Excel Hilfe" wurde erstellt von Marius82, 27. Juli 2012.

  1. Marius82 Erfahrener User

    VBA Schleife zu umständlich, Wie gehts besser?


    Hallo,<O:p></O:p>
    ich habe eine Frage zu einer Schleife in VBA. Ich habe einen Code geschrieben in der verschiedene Schleifen abgearbeitet werden. Dieser Code funktioniert auch soweit wie ich mir das gedacht habe. Nur leider ist im Modul 2 unter dem Punkt ‚“AP schreiben“ einige If-Abfragen die ich als „unschön“ bzw überflüssig empfinde.
    Code:
     Option Explicit
        Public NUMMER As String
        Public MGR As String
        Public KST As String
        Public RUESTEN As Double
        Public lng As Long
        Public Zeile As Long
    Sub Nummer_aufloesen()
    '*****************************************************************************************************************
    'Blatt leeren
    With Worksheets("AP")
        .Range("A2:AH1048576").ClearContents
        .Range("A1:AH1048576").Borders(xlInsideHorizontal).LineStyle = xlNone
    End With
    '*****************************************************************************************************************
        Worksheets("A").Select
        
        lng = Cells(1048576, 1).End(xlUp).Row
        
        For Zeile = 1 To lng Step 1
            Worksheets("A").Select
                NUMMER = Cells(Zeile, 1)
                MGR = Mid(Cells(Zeile, 2), 24, 5)
                KST = Mid(Cells(Zeile, 2), 29, 5)
                RUESTEN = Right(Cells(Zeile, 2), 5) / 100
    '*****************************************************************************************************************
                Call umschluesseln
    '*****************************************************************************************************************
       'Ap schreiben
                Worksheets("AP").Select
                    If Cells(Zeile + 1, 19) > "0" Then
                        Else
                            If RUESTEN = "0" Then
                                Cells(Zeile + 1, 19) = RUESTEN_FEST
                                RUESTEN_FEST = "0"
                            End If
                    End If
                
                    If RUESTEN > "0" Then
                        Cells(Zeile + 2, 19) = RUESTEN
                        Else
                        Cells(Zeile + 1, 1) = NUMMER
                    End If
        Next
        
    '*****************************************************************************************************************
    'leere Zeilen löschen
        lng = Cells(1048576, 1).End(xlUp).Row
        For Zeile = lng To 2 Step -1
            If Cells(Zeile, 1) = "" Then
                Rows(Zeile).Delete
            End If
        Next
    '*****************************************************************************************************************
    End Sub
    Leider fällt mir keine andere Lösung ein als den Wert aus der Variable zwei Zeilen tiefer zu schreiben, im zweiten durchlauf in dieser Zeile kontrollieren ob etwas drin steht und im Nachgang diese Zeilen zu löschen. Da muss es doch einen einfacheren Weg geben?

    Um mein Problem leichter zu verstehen habe ich die Datei im Anhang.<O:p></O:p>
    Ich benutze Office 2010<O:p></O:p>
    Danke.<O:p></O:p>
    <O:p></O:p>
     
    Marius82, 27. Juli 2012
    #1
  2. fette Elfe Erfahrener User
    Hallo Marius,

    wegen gerade begrenzter Zeit habe ich mir Deine Mappe noch nicht angeschaut, sondern nur anhand des oben geposteten Codes gearbeitet.

    Hier mal ein paar Anmerkungen, die mir auf die Schnelle aufgefallen sind:
    Code:
    Option Explicit
    
    Public NUMMER As String         ' immer 1. Buchstabe eines Wortes im Var.-Namen groß, den Rest klein ... ist übersichtlicher
    Public MGR As String            ' benutze ein Typenpräfix
    Public KST As String
    Public RUESTEN As Double        ' benötigst Du die Variablen wirklich "Public"
    Public lng As Long              ' vermeide nur das Typenpräfix als Var.-Namen zu benutzen, vergebe "sprechende" Namen
    Public Zeile As Long
    
    
    Sub Nummer_aufloesen()
    '*****************************************************************************************************************
    'Blatt leeren
    With Worksheets("AP")
        .Range("A2:AH1048576").ClearContents        ' hier würde ich vorher schon die letzte benutzte Zeile suchen und als untere Begrenzung verwenden um den bereich möglichst klein zu halten
        .Range("A1:AH1048576").Borders(xlInsideHorizontal).LineStyle = xlNone
    End With
    '*****************************************************************************************************************
        Worksheets("A").Select                      ' vermeide "select". ist fast immer unnötig
        
        lng = Cells(1048576, 1).End(xlUp).Row       ' die Referenzierung von "Cells" ist nicht sauber, kann zu Fehlern führen
        
        For Zeile = 1 To lng Step 1                 ' "Step 1" ist "default", muss nicht geschrieben werden
            Worksheets("A").Select
                NUMMER = Cells(Zeile, 1)            ' wieder Referenzierung unsauber
                MGR = Mid(Cells(Zeile, 2), 24, 5)
                KST = Mid(Cells(Zeile, 2), 29, 5)
                RUESTEN = Right(Cells(Zeile, 2), 5) / 100
    '*****************************************************************************************************************
                Call umschluesseln
    '*****************************************************************************************************************
       'Ap schreiben
                Worksheets("AP").Select             ' vermeide "select". ist fast immer unnötig
                    If Cells(Zeile + 1, 19) > "0" Then  ' dann.. ja was dann? da steht nix...
                        Else
                            If RUESTEN = "0" Then
                                Cells(Zeile + 1, 19) = RUESTEN_FEST
                                RUESTEN_FEST = "0"
                            End If
                    End If
                
                    If RUESTEN > "0" Then           ' die gleiche Abfrage steht schon weiter oben, ausserdem ist die Variable als Zahl deklariert, Du fragst aber auf einen String ab
                        Cells(Zeile + 2, 19) = RUESTEN
                        Else
                        Cells(Zeile + 1, 1) = NUMMER
                    End If
        Next                                        ' "next" was?  besser die Schleifenvariable angeben
        
    '*****************************************************************************************************************
    'leere Zeilen löschen
        lng = Cells(1048576, 1).End(xlUp).Row
        For Zeile = lng To 2 Step -1
            If Cells(Zeile, 1) = "" Then
                Rows(Zeile).Delete
            End If
        Next
    '*****************************************************************************************************************
    End Sub
    Und die Schreibweise, wie ich es vermutlich machen würde (wie gesagt, ohne bisher die Mappe gesehen zu haben):
    Code:
    Option Explicit
    
    Dim lngLastRow As Long
    Dim lngRow As Long
    
    Dim dblRuesten As Double
    
    Dim strNummer As String
    Dim strMGR As String
    Dim strKST As String
    
    
    Public Sub Nummer_aufloesen()
    
    With ThisWorkbook
    
    'Blatt leeren
        With .Worksheets("AP")
            lngLastRow = .UsedRange.Rows(.UsedRange.Rows.Count).Row
            .Range("A2:AH" & lngLastRow).ClearContents
            .Range("A1:AH" & lngLastRow).Borders(xlInsideHorizontal).LineStyle = xlNone
        End With
        
        With .Worksheets("A")
            
            lngLastRow = .UsedRange.Rows(.UsedRange.Rows.Count).Row
            
            For lngZeile = 1 To lngLastRow
                strNummer = .Cells(Zeile, 1)
                strMGR = Mid(.Cells(Zeile, 2), 24, 5)
                strKST = Mid(.Cells(Zeile, 2), 29, 5)
                dblRuesten = Right(.Cells(Zeile, 2), 5) / 100
        
                Call umschluesseln
        
            'Ap schreiben
                With .Worksheets("AP")
                    
            ' diesen Teil entweder:
                    If .Cells(Zeile + 1, 19) > "0" Then
                        ' hier kommt dann noch Dein Code, was auch immer...
                    ElseIf dblRuesten = 0 Then
                        .Cells(Zeile + 1, 19) = RUESTEN_FEST
                        RUESTEN_FEST = "0"                      ' was ist "RUESTEN_FEST" ??? eine Zahl oder ein String?
                    End If
                
                    If dblRuesten > "0" Then
                        .Cells(Zeile + 2, 19) = dblRuesten
                    Else
                        .Cells(Zeile + 1, 1) = strNummer
                    End If
                    
            ' oder: (kannst nur Du entscheiden, nur Du kennst die Kriterien wirklich
                    If dblRuesten > "0" Then
                        If .Cells(Zeile + 1, 19) > "0" Then
                            .Cells(Zeile + 1, 19) = RUESTEN_FEST
                            RUESTEN_FEST = "0"
                        End If
                        .Cells(Zeile + 2, 19) = dblRuesten
                    Else
                        .Cells(Zeile + 1, 1) = strNummer
                    End If
                    
                End With        ' .Worksheets("AP")
                
            Next lngZeile
            
        End With                ' .Worksheets("A")
        
    'leere Zeilen löschen
        With .Worksheets("AP")
            lngLastRow = .UsedRange.Rows(.UsedRange.Rows.Count).Row
            For lngZeile = lng To 2 Step -1
                If .Cells(lngZeile, 1) = "" Then
                    .Rows(Zeile).EntireRow.Delete shift:=xlUp
                End If
            Next
        End With                ' .Worksheets("AP")
        
    End With                    ' With ThisWorkbook
    
    End Sub

    Und hier noch ein paar Links, die ich Dir wärmstens ans Herz legen möchte:
    http://www.it-academy.cc/article/995/Ungarische+Notation+fuer+Visual+Basic.html
    http://www.xoc.net/standards/rvbanc.asp
    http://support.microsoft.com/kb/110264/en-us
    http://xlam.ch/pos/rules.htm

    Später (heute Abend) kann ich dann gern auch mal in die Mappe schauen.



    Ich hoffe geholfen zu haben.
     
    fette Elfe, 27. Juli 2012
    #2
  3. Marius82 Erfahrener User
    Danke schon mal das du dich durch meinen wohl ehr schlecht als rechten Code gewühlt hast.
    Ich werde mir deine Bemerkungen zu Herzen nehmen! Stehe halt noch am Anfang von VBA...
    Wäre wirklich toll, wenn du dir meine Mappe mal anschauen könntest!!!
    Noch eine Frage, die Variablen mit einem Typenpräfix u´zu benennen hat nur den Hintergrund auf dem ersten Blick zu sehen um was für einen Datentyp es sich handelt? Oder hat das noch einen tieferen Sinn der mir entgangen ist?

    Danke
     
    Marius82, 27. Juli 2012
    #3
  4. Exl121150 Erfahrener User

    VBA Schleife zu umständlich, Wie gehts besser?

    Hallo,

    vielleicht wie in der beiliegenden Datei?
     
    Exl121150, 27. Juli 2012
    #4
  5. fette Elfe Erfahrener User
    Hallo Marius,

    Wir haben alle mal angefangen...


    Habe ich gemacht, und ich denke, Anton hat Dir ne schöne saubere Lösung geliefert.
    ;)


    Naja, definiere "nur".
    Es hat "nur" den Sinn, auf Anhieb sehen zu können von welchem Typ die Variable ist, da hast Du recht.
    Allerdings, beinhaltet dieses "nur" eben die Möglichkeit sich auch bei komplexen und umfangreichen Projekten schnell einlesen und zurecht zu finden zu können.
    Egal ob Du noch beim Entwickeln bist, nach Wochen oder Monaten mal wieder reinschaust weil etwas überarbeitet werden muss, Du irgendwann nochmal reinschaust "Wie habe ich das damals denn gelöst?", oder jemand anderes Deinen Code liest...

    Das ist eins der Dinge, die mir an VBA so gut gefallen: die vorgegebenen Elemente sind, soweit man des Englischen mächtig ist, ziemlich einfach zu entschlüsseln, wenn man erstmal den Einstieg gefunden hat.
    Und wenn man dann noch bei allen Benennungen auf möglichst "sprechende" Namen achtet, ist VBA fast wie Klarschrift (überspitzt gesagt).

    Finde ich zumindest.
    (inzwischen, am Anfang habe ich auch nur "Bahnhof Kofferklauen" verstanden ...)
    ;)
     
    fette Elfe, 27. Juli 2012
    #5
  6. Marius82 Erfahrener User
    Danke für eure Hilfe, so sieht die Sache schon professioneller aus!
    Aber ist nicht trotzdem noch ein Schritt zuviel in dem Ablauf? Das löschen der leeren spalten zum Schluss ist ja immer noch notwendig. Kann man den Schritt nicht weg lassen, dh das man vorher schon eine Zeile nach oben rutscht, anstatt im Nachgang die Spalten zu löschen?

    Und noch zwei Sachen die ich nicht verstehe:
    Code:
    Public Function Umschluesseln1(KST$, MGR$) As Double
    Wofür steht das "$" hinter KST und MGR?

    Code:
    RUESTEN_Zeile2 = 0#
    Wofür steht die "#" hinter der Null?

    Danke!

    Und noch eine Frage, ich hab jetzt immer alles mit dem Excel VBA programmiert. Jetzt hab ich von Microsoft das Visual Studio 2010 Express gefunden- kann man da auch etwas mit anfangen um in Excel zu arbeiten?
     
    Zuletzt bearbeitet: 27. Juli 2012
    Marius82, 27. Juli 2012
    #6
  7. Exl121150 Erfahrener User
    Hallo,

    In (Visual) BASIC gibt es (inzwischen) 2 Möglichkeiten, den Datentyp von Variablen zu deklarieren:
    1) die ursprüngliche Methode, die seit den Anfangszeiten von BASIC möglich ist: indem man im DIM-Statement die Variable anführt, gefolgt von einem Typkennzeichner ($ steht dabei für Stringtyp, # steht für Double-Typ, ! steht für Single-Typ, % für 16-Bit-Integer, & für 32-Bit-Integer, @ steht für Currency-Typ). Aber Du wirst bald feststellen, dass es nicht für jeden Datentyp ein solches Datentyp-Suffix-Zeichen gibt, insbesondere natürlich nicht für benutzerdefinierte Datentypen oder Objektklassen-Typen.
    2) Deshalb wurde diese Methode später ergänzt durch die Deklaration " AS Typbezeichner ".
    Man könnte die Funktionsdeklaration: Public Function Umschluesseln1(KST$, MGR$) As Double
    auch so schreiben: Public Function Umschluesseln1(KST As String, MGR As String) As Double
    oder auch so schreiben: Public Function Umschluesseln1#(KST$, MGR$)

    Mit dem Wissen von vorhin kannst Du schon erraten, was das "0#" bedeuten soll: Dadurch wird dem Compiler/Interpreter mitgeteilt, dass es sich nicht um eine beliebige Null handelt, sondern um eine Null vom Double-Typ. Also man kann dieses Suffixverfahren nicht bloß im DIM-Statement anwenden, sondern auch im Programmtext sowohl bei Variablen als auch bei Konstanten. Tut man das, so dürfen sich bei einer bestimmten Variablen der Typ in der DIM-Anweisung und der Typ im Programmtext sich nicht widersprechen, sie müssen identisch sein.
    In der Zwischenzeit hat sich bei Variablen eine 2. Methode herausentwickelt, damit man der Variablen schon ansieht, welchen Typ sie hat: indem man in den Variablennamen ein Typ-Präfix aufnimmt. Diese Methode kommt aus anderen Programmiersprachen, in denen es die BASIC-Suffix-Methode nicht gibt.
    So kann man dann zB. in diversen Programmen statt "Pfad$" lesen "strPfad" - oder auch in Excel-Makros Variablen wie "rngBereich" finden, um durch die ersten 3 Zeichen im Namen anzudeuten, dass diese Variable den Objektklassen-Typ "RANGE" besitzt.

    Dieses ist eine komplette Entwicklungsumgebung, in der man fertig kompilierte Programme erstellen kann, die im Allgemeinen völlig unabhängig von den Office-Programmen arbeiten. Als Programmiersprache ist neben BASIC auch C in diversen Varianten möglich.
    Man kann so, wenn man sich auskennt, für die Office-Programme sogenannte "Add-Ins" erstellen - oder auch Spread-Sheets programmieren unabhängig von Excel - oder ganze Objektbibliotheken programmieren, die per Verweis im VBA-Editor eingebunden werden können.
    In dem dort enthaltenen BASIC-Dialekt sind natürlich weit mehr Dinge möglich als in VBA. Andererseits enthält das Office-VBA natürlich von Haus aus die ganze Palette von Objekten der betreffenden Office-Applikation.
     
    Zuletzt bearbeitet: 28. Juli 2012
    Exl121150, 28. Juli 2012
    #7
  8. Marius82 Erfahrener User

    VBA Schleife zu umständlich, Wie gehts besser?

    Danke für die vielen Hintergrund Informationen!!!

    Ich habe nochmal eine Frage zu der Lösung von "Exl121150"

    Was wäre wenn ich zwei oder mehrere Werte umschlüsseln müßte? Müsste ich dann für jeden Wert den ich aus der Tabelle wiedergeben möchte eine neue Public Function schreiben? Also die selbe Function nur dann mit
    Code:
    Umschluesseln2 = .Cells(4).Value
    ?

    Hier nochmal das Original von Exl121150:

    Code:
    Public Function Umschluesseln1(KST$, MGR$) As Double
      Dim rgSuch As Range, Ws As Worksheet, rgTab As Range
      Dim strAdresse As String
      Dim Fest As Double
      
      Set Ws = Worksheets("US_MGR_ARBPL")
      Set rgTab = Ws.Cells(1, 1).CurrentRegion
      
      Umschluesseln1 = 0#
      For Each rgSuch In rgTab.Rows
        With rgSuch
          If .Cells(1).Value = Left(KST$, 3) Then
            If .Cells(2).Value = CLng(MGR) Then
              Umschluesseln1 = .Cells(3).Value
              Exit For
            End If
          End If
        End With
      Next rgSuch
      
    End Function
    Danke
     
    Marius82, 30. Juli 2012
    #8
  9. Exl121150 Erfahrener User
    Hallo,
    was meinst Du genau mit "zwei oder mehrere Werte umschlüsseln"?

    Wenn Du damit meinst, dass Du auf ein und dieselbe Tabelle, die sich ab Zelle A1 im Arbeitsblatt "US_MGR_ARBPL" befindet, Abfragen machen möchtest mit verschiedenen Kombinationen für KST$ und MGR$, warum solltest Du dann die Funktion "Umschluesseln1" mehrfach programmieren müssen? Es genügt dann, diese Funktion einfach mehrfach aufzurufen mit eben verschiedenen Parametern, zB:
    a# = Umschluesseln1("544AB","40")
    b# = Umschluesseln1("544AC","50")
    Dadurch erhalten die beiden Double-Variablen a# und b# die Werte, die in Spalte C der Tabelle aus Arbeitsblatt "US_MGR_ARBPL" enthalten sind und die passenden Werte in Spalte A bzw. B besitzen (Zeile 6: 544 + 40 -> 4 bzw. Zeile 7: 544 + 50 -> 0,6)
    a# = 4
    b# = 0,6

    Wenn Du aber damit meinst, dass Du außer in Spalte C in obiger Tabelle noch in weiteren Spalten (D, E, ...) weitere Werte platzieren möchtest, die mithilfe der Werte der ersten beiden Spalten (A, B) gefunden werden sollen, dann muss die Funktion in einzelnen Details anders programmiert werden, zB:
    Code:
    Public Function Umschluesseln2(KST$, MGR$, Optional Anz% = 1) As Range
      Dim Ws As Worksheet
      Dim rgSuch As Range, rgTab As Range
      
      'Ermittle Tabelle "rgTab" im Arbeitsblatt "US_MGR_ARBPL"
      Set Ws = Worksheets("US_MGR_ARBPL")
      Set rgTab = Ws.Cells(1, 1).CurrentRegion
      
      'Suche LINKS(KST$;3), MGR$ in den ersten 2 Spalten von "rgTab"
      For Each rgSuch In rgTab.Rows
        With rgSuch
          If .Cells(1).Value = Left$(KST$, 3) Then
            If .Cells(2).Value = CLng(MGR) Then
              'Suche erfolgreich: gibt 'Anz' Zellen als Wertebereich zurück:
              Set Umschluesseln2 = .Resize(1, Anz%).Offset(0, 2)
              Exit Function
            End If
          End If
        End With
      Next rgSuch
      'LINKS(KST$;3), MGR$ wurden in Tabelle "rgTab" nicht gefunden:
      'Gib 'Anz' leere Zellen als Wertebereich zurück
      Set Umschluesseln2 = rgTab.Resize(1, Anz%).Offset(rgTab.Rows.Count)
      
    End Function
    
    
    Diese Funktion besitzt jetzt 3 Parameter, wobei die ersten beiden identisch zur Funktion "Umschluesseln1" sind. Der 3. Parameter gibt die Spaltenanzahl der zurückgelieferten Resultatszeile an. Diese Funktion liefert jetzt nicht mehr einzelne Double-Werte zurück, sondern Zellbereiche, die aus 1 Zeile bestehen und eine Breite von Anz% Zellen haben. Dieser zurückgegebene Zellbereich beginnt jeweils in Spalte C der vorgenannten Tabelle, wobei die Zellen in Spalte A und B dieser Zeile identisch sind mit den beiden 1. Parametern (LINKS(KST$;3) bzw. MGR$).
    Als Musterbeispiel zur Verwendung dieser Funktion:
    Code:
    Sub Test()
      Dim a#, b#
      With Umschluesseln2("544R233", "40", 2)
        a = CDbl(.Cells(1).Value): b = CDbl(.Cells(2).Value)
      End With
    End Sub
    
    Dadurch erhält die Variable a# den Wert aus Spalte C und die Variable b# den Wert aus Spalte D aus derjenigen Zeile, die in Spalte A den Wert "544" und in Spalte B den Wert "40" enthält. Das wäre also in Deinem Musterbeispiel:
    a# = 4 und b# = 0 ( da eine leere Zelle in 0 umgewandelt wird durch die Funktion CDBL(..) )
    Der neue 3. Parameter in der Funktion "Umschluesseln2" kann auch weggelassen werden. Tut man das bei einem Funktionsaufruf, wird angenommen, dass der als Resultat zurückgegebene Zellbereich eine Breite von 1 Zelle hat.
    zB. folgender Aufruf:
    a# = Umschluesseln2("544ABC","50").value
    liefert:
    a# = 0,6
    aus Deinen Beispieldaten.
     
    Zuletzt bearbeitet: 30. Juli 2012
    Exl121150, 30. Juli 2012
    #9
  10. Marius82 Erfahrener User
    Hallo,

    mit meiner Frage meine ich,
    In meinem Beispiel würde ich zB. Daten aus der Spalte C und aus der Spalte D suchen.

    Wie rufe ich denn dann Daten aus Spalte D auf? Dein allgemeiner Code:
    Code:
    Sub Test()
      Dim a#, b#
      With Umschluesseln2("544R233", "40", 2)
        a = CDbl(.Cells(1).Value): b = CDbl(.Cells(2).Value)
     End With
    End Sub
    verstehe ich nicht. Kannst du das nochmal an meinem Beispiel zeigen?

    Danke
     
    Marius82, 1. August 2012
    #10
  11. Exl121150 Erfahrener User
    Hallo,

    die neue Funktion "Umschluesseln2", die ich Dir zuletzt gepostet habe, macht Folgendes:
    1) Sie hat 3 Parameter: KST$ und MGR$ und Anz%; über diese 3 Parameter kann sie gesteuert werden und zwar:
    1a) So wie die Funktion konstruiert ist, nimmt sie die linken 3 Zeichen von KST$ (also ähnlich wie die Arbeitsblattformel LINKS(KST$;3)) und sucht damit einen passenden Wert in Spalte A des Arbeitsblattes "US_MGR_ARBPL".
    1b) Hat sie einen solchen gefunden, schaut sie nach, ob auch der Wert in Spalte B zum 2. Parameter MGR$ passt.
    1c) War die Funktion in Punkt 1b) nicht erfolgreich, geht sie wieder nach Punkt 1a) und sucht dort weiter.
    1d) War die Funktion in Punkt 1b) erfolgreich, gibt sie als Resultat den Zellbereich zurück, der sich in der gleichen Zeile wie die beiden gefundenen Schlüsselbegriffe KST$ und MGR$ befinden: und zwar die Zellen ab Spalte C. Wie viele Zellen das sind, das regelt der 3. Parameter Anz%.

    Also gibt die Funktion "Umschluesseln2" nicht Werte zurück, sondern einen Zellbereich (oder in der Sprache der Excel-Arbeitsblätter: einen (Zell-)Bezug).
    Zellbezüge/Zellbereiche werden im Excel-VBA als RANGE-Objekte bezeichnet. Sie (=die Objektinstanzen der RANGE-Objektklasse) können mit den Eigenschaften und Methoden dieser Objekteklasse bearbeitet werden. Darum hat diese Funktion als Ergebniswert/typ nicht zB. " As Double" oder " As Single" oder Ähnliches, sondern " As Range" (vgl. Ende der 1. Zeile der Funktion).
    Ein Zellbereich seinerseits besteht wieder aus mehreren Zellen, die von 1 bis ... durchnummeriert werden können. Also bewirkt ein Formelausdruck wie
    Umschluesseln2("544R233", "40", 2).Cells(2).Value
    Folgendes: Zuerst einmal sucht die Funktion "Umschluesseln2" in Spalte A bzw. B von Arbeitsblatt "US_MGR_ARBPL" nach der Zeile, die dort "544" bzw. "40" stehen hat. War die Suche erfolgreich, liefert sie aus dieser Zeile ab Spalte C (also Spalte C und D) einen Zellbereich mit 2 Zellen zurück.
    Da die Funktion vom Ergebnistyp "RANGE" ist, kann schließlich auf die Eigenschaften und Methoden dieses Objektklassentyps zugegriffen werden. In diesem Fall wird die CELL-Methode des Range-Typs verwendet. Die Zahl 2 als Parameter dieser Range-Methode ist genau die Zellnummer innerhalb des Zellbereiches.
    Was die Schreibweise betrifft, so hat sich in der Welt der objektorientierten Programmierung folgende Konvention/Syntax herausgebildet:
    Man schreibt zuerst die Objektinstanz, gefolgt von einem Punkt und dann die Eigenschaft/Methode/Ereignis dieser Instanz.
    In diesem Fall also: Umschluesseln2(....).Cells(...).Value
    Also Du siehst, in diesem Fall gibt es sogar 2x einen Punkt: vor Cells und auch vor Value. D.h. ...Cells(2) stellt ja seinerseits wieder einen Zellbereich dar (zwar bestehend nur aus 1 Zelle) und auf diesen Bereich (also auf die 2. Zelle des von Umschluesseln2 zurückgelieferten Zellbereiches) wird wieder eine Bereichsmethode angewandt, nämlich Value. Diese Methode schließlich liefert erst den Zellwert dieser 2. Zelle zurück.
    Die von Dir nicht verstandene Codepassage könnte ich auch so schreiben:
    Code:
    Sub Test()
      Dim a#,b#
      Dim Resultat as Range
      Set Resultat = Umschluesseln2("544R233", "40", 2)
      a# = CDbl(Resultat.Cells(1).Value)
      b# = CDbl(Resultat.Cells(2).Value)
    End Sub
    
    Dieser Code müsste jetzt verständlich sein bis auf das Wörtchen "set". Da die Funktion Umschluesseln2 eine Objektinstanz als Ergebnis zurückliefert und diese an die Variable "Resultat" zugewiesen werden soll, so darf in VBA nicht die gewöhnliche Zuweisungsanweisung (mit LET) genommen werden, sonden muss "SET" genommen werden (Anm.: VBA-intern wird nämlich nicht ein gewöhnlicher Wert zugewiesen, sondern ein Pointer auf die resultierende Objektinstanz).
    Da im obigen Code mehrmals die Objektvariable Resultat vorkommt, gibt es auch eine abkürzende Schreibweise mit "With":
    Code:
    Sub Test()
      Dim a#, b#
      Dim Resultat As Range
      Set Resultat = Umschluesseln2("544R233", "40", 2)
      With Resultat
         a# = CDbl(.Cells(1).Value)
         b# = CDbl(.Cells(2).Value)
      End Resultat
    End Sub
    
    Überall dort, wo ein einsamer Punkt vor einer Eigenschaft bzw. Methode eines Objekt steht, muss man sich das Objekt, das nach With angegeben ist, davorstehend hindenken (innerhalb eines With ... End With-Blockes).
    Und schließlich kann man das nochmals, wie folgt, verkürzen:
    Code:
    Sub Test()
      Dim a#, b#
      With Umschluesseln2("544R233", "40", 2)
        a# = CDbl(.Cells(1).Value)
        b# = CDbl(.Cells(2).Value)
      End With
    End Sub
    
    Da man in BASIC seit eh und je mehrere Anweisungen in eine Zeile schreiben darf, sofern man sie mit einem Doppelpunkt trennt, so kann man auch schreiben:
    Code:
    Sub Test()
      Dim a#, b#
      With Umschluesseln2("544R233", "40", 2)
        a# = CDbl(.Cells(1).Value):    b# = CDbl(.Cells(2).Value)
      End With
    End Sub
    
     
    Zuletzt bearbeitet: 1. August 2012
    Exl121150, 1. August 2012
    #11
  12. Marius82 Erfahrener User
    Alles klar, danke!
    Jetzt hab ich es verstanden und auch schon umgesetzt.
     
    Marius82, 2. August 2012
    #12
Thema:

VBA Schleife zu umständlich, Wie gehts besser?

Die Seite wird geladen...
  1. VBA Schleife zu umständlich, Wie gehts besser? - Similar Threads - VBA Schleife umständlich

  2. VBA Schleife kopieren und einfügen von Spalten

    in Microsoft Excel Hilfe
    VBA Schleife kopieren und einfügen von Spalten: Hallo Zusammen, Ich habe auf einem Tabellenblatt eine variable Anzahl an Spalten mit Daten die auch eine variable Anzahl an Zeilen haben, auch mit Lücken in den Zeilen. Die Spalten mit den Infos...
  3. Eine Schleife mit zwei tebellen vba Access

    in Microsoft Access Hilfe
    Eine Schleife mit zwei tebellen vba Access: Hallo zusammen! Es gibt’s zwei Tabellen und ich wollte aus zweiter Tabelle die Daten nach einem Kriterium (FLTR=0) an erste Tabelle übertragen (kopieren). Geht aber nicht. Hier ist mein Kode,...
  4. VBA Loop : Werte suchen und löschen

    in Microsoft Excel Hilfe
    VBA Loop : Werte suchen und löschen: Hallo zusammen, ich habe folgende Ausgangslage: Im Tabellenblatt Auswahl sollen Artikel eingegeben werden und via Formel wird der zugehörige Lagerplatz ausgegeben (funktioniert soweit), sodass...
  5. VBA: Variable Anzahl Zeilen mit Suchkriterien finden und kopieren

    in Microsoft Excel Hilfe
    VBA: Variable Anzahl Zeilen mit Suchkriterien finden und kopieren: Hallo zusammen, ich konnte bislang nur bruchstückhafte Ansätze zu meinem Problem finden, jedoch keinen um mehrere Kriterien zu erfassen und anschließend zu ordnen, daher brauche ich (mal wieder)...
  6. VBA: Datum automatisch hinzufügen nach Übertrag

    in Microsoft Excel Hilfe
    VBA: Datum automatisch hinzufügen nach Übertrag: Hallo zusammen, ich habe ein Makro gebaut, welches die Daten aus dem Tabellenblatt Bestellformular kopiert und diese in ein anderes Tabellenblatt (Bestellhistorie) überträgt, wobei zusätzlich in...
  7. Excel VBA Exit aus der Schleife verhindern

    in Microsoft Excel Hilfe
    Excel VBA Exit aus der Schleife verhindern: Hallo, ich denke, ich habe ein tatsächlich einfaches Problem. Komme aber nicht auf die Lösung. In dieser Schleife x bis 507 wird eine Funktion aufgerufen, die in einer anderen Liste einen Namen...
  8. Userform Schleife

    in Microsoft Excel Hilfe
    Userform Schleife: Hallo, ich erstelle über userform eine schöne Oberfläche wo ich verschiedene Sachen abfrage. Das funktioniert auch alles, aber mein Problem jetzt ist, dass ich die Werte in einen bestimmten Excel...
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Auf dieser Website werden Cookies für die Zugriffsanalyse und Anzeigenmessung verwendet.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden