Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1380to1384
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Makro Reiterverweismatrix

Makro Reiterverweismatrix
05.09.2014 17:30:33
Steffen

Hallo liebe Excler!
Ich habe ein Makro erstellt, welches mir in einer Matrix die Anzahl der Verweise von Sheet zu Sheet auflisten soll.
Dazu werden 2 Sheets angelegt: (1) SheetMatrixOverview & (2) SheetSearchList
Prinzip:
1. A: Reiternamen auflisten
2. Loop ersten Suchbegriff (reiternamen) aus A auswählen und die komplette Mappe danach durchsuchen, bei Treffern:
3. C: Zelle eintragen
4. D: Reiter (in dem Verweis gefunden wurde) eintragen
5. nächster Suchbegriff aus A
Problem: Ich möchte das Makro effizienter und robuster machen, indem die Mappe nur einmal nach allen Suchbegriffen gleichzeitig durchsucht wird (Bei 100 Reitern mit Werten wird das Makro extrem langsam -> ExcelCrash)
Ich habe mich dem Problem versucht via Array oder ähnlichem anzunähern und komme nicht weiter.
und später noch:
6. via indirect Wert auslesen und einige andere Formeln
Die Originalexcel kann ich leider nicht hochladen, da sie extrem groß ist.
Hier der VBA-Code:

Sub Hirn()
Dim strFilename As String
Dim wkbMappe As Workbook 'neue Mappe
Dim AmountSheets As Long 'Reiteranzahl auslesen
Dim WS As Worksheet
For Each WS In ActiveWorkbook.Worksheets
WS.Visible = xlSheetVisible
Next WS
Application.Calculation = xlCalculationManual 'automat.Berechnung ausschalten
ChDrive "c:\"
ChDir "\temp\"
strFilename = ("SheetLinksMatrixOverview" & Format(Date, "yyyymmdd") & ".xlsx")
Application.Dialogs(xlDialogSaveAs).Show (strFilename)
strFilename = ActiveWorkbook.Name
'SheetMatrixOverview
For Each WS In Worksheets
If WS.Name = "SheetMatrixOverview" Then WS.Delete
Next WS
Worksheets.Add Before:=Worksheets(1)
ActiveSheet.Name = "SheetMatrixOverview"
'SheetSearchList
For Each WS In Worksheets
If WS.Name = "SheetSearchList" Then WS.Delete
Next WS
Worksheets.Add after:=Worksheets(1)
ActiveSheet.Name = "SheetSearchList"
' Suchlegende erstellen mit Umbennenung in Folgespalte
Sheets("SheetSearchList").Activate
For AmountSheets = 3 To Workbooks(strFilename).Worksheets.Count '5 durch 2 ersetzen
Cells(1, 1).Value = "Suchbegriffe:"
Cells(AmountSheets - 1, 1).Value = "'" & Workbooks(strFilename).Sheets(AmountSheets). _
Name & "'!"
Next AmountSheets
' Begin Suchschleife nach Begriffen in Spalte B ab B2
Dim X As Integer
X = 2
Do Until IsEmpty(Worksheets("SheetSearchList").Cells(X, 1))
B = Worksheets("SheetSearchList").Cells(X, 1)
Dim strFind As String
Dim rng As range
Dim strAddress As String
Dim Z As Integer
strFind = B
If strFind = "" Then MsgBox ("idiot") ' <- höhö
For Each WS In Worksheets
Set rng = WS.Cells.Find(strFind)
If Not rng Is Nothing Then
strAddress = rng.Address
Do
On Error GoTo Error
Application.Goto rng
With Worksheets("SheetSearchList")
Z = 1
Do Until IsEmpty(Worksheets("SheetSearchList").Cells(Z + 1, 3))
Z = Z + 1
Loop
Z = Z + 1
Worksheets("SheetSearchList").Cells(Z, 3) = rng.Address
Worksheets("SheetSearchList").Cells(Z, 4) = rng.Worksheet.Name
End With
Set rng = WS.Cells.FindNext(after:=ActiveCell)
Loop While rng.Address <> strAddress
End If
Next WS
'Application.Goto Worksheets(1).Range("A1")    Später
Set rng = Nothing
X = X + 1
Loop
Sheets("SheetSearchList").Activate
'2te Tabelle
Worksheets("SheetSearchList").Cells(1, 3) = "Cell:"
Worksheets("SheetSearchList").Cells(1, 4) = "Location:"
Worksheets("SheetSearchList").Cells(1, 5) = "Value:"
Worksheets("SheetSearchList").Cells(2, 5).FormulaLocal = "=IF(AND(C2=""""; _
D2="""");"""";INDIRECT(""'""&D2&""'!""&C2))"
'Für die dritte Tabelle
Dim AmountSearchedSheets As Long
AmountSearchedSheets = range(range("A1"), range("A1").End(xlDown)).Rows. _
Count
'dritte Tabelle
Worksheets("SheetSearchList").Cells(1, 7) = "Auf wen wird verlinkt:"
Worksheets("SheetSearchList").Cells(2, 7).FormulaLocal = "=IF(AND(C2=""""; _
D2="""");"""";IF(ISNUMBER(MATCH(E2;$A$2:$A$" & AmountSearchedSheets & ";0));E2;G1))"
Worksheets("SheetSearchList").Cells(2, 8).FormulaLocal = "=IF(G2="""";""""; _
LEFT(G2;LEN(G2)-2))"
'Fürs Runterziehen
Dim AmountValues As Long
AmountValues = range(range("C2"), range("C2").End(xlDown)).Rows.Count + 1
'Runterziehen
range("E2:H2").Select
Selection.Copy
range("E2:H" & AmountValues + 1).Select
ActiveSheet.Paste
Application.CutCopyMode = False
'Matrixformel
Sheets("SheetMatrixOverview").Activate
For AmountSheets = 3 To Workbooks(strFilename).Worksheets.Count
Cells(AmountSheets - 1, 1).Value = Workbooks(strFilename).Sheets( _
AmountSheets).Name
Cells(1, 1).Value = "Matrix:"
Cells(1, AmountSheets - 1).Value = Workbooks(strFilename).Sheets( _
AmountSheets).Name
Next AmountSheets
Worksheets("SheetMatrixOverview").Cells(2, 2).FormulaLocal = "=COUNTIFS( _
SheetSearchList!$D$2:$D$" & AmountValues & ";SheetMatrixOverview!$A2;SheetSearchList!$H$2:$H$" & AmountValues & ";SheetMatrixOverview!B$1)"
'Letzten Spaltenbuchstaben
Dim strAdd As String
Dim strLetter As String
strAdd = Mid((Cells(1, AmountSearchedSheets).Address), 2, Len(Cells(1,  _
AmountSearchedSheets).Address) - 3)
'Matrix runterziehen
range("B2").Select
Selection.Copy
range("B2:" & strAdd & AmountSearchedSheets).Select
ActiveSheet.Paste
Application.CutCopyMode = False
Application.Calculation = xlCalculationAutomatic 'automat.Berechnung einschalten
Exit Sub
Error:
Application.Calculation = xlCalculationAutomatic 'automat.Berechnung  _
einschalten falls ein Fehler ausgegeben wird
MsgBox ("Error 404 - Page not Found")
End Sub

Viel Spaß beim tüffteln!
Wenn ich eine Lösung finde werde ich sie hier posten!

24
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Makro Reiterverweismatrix
05.09.2014 17:46:31
Franc
Wenn es nirgends anders ausgeschaltet wird dann fehlt schon mal das hier
am anfang
Application.ScreenUpdating = False
am ende vor "exit sub" und auch einmal bei "Error:"
Application.ScreenUpdating = True
Das löst evtll schon das Problem

AW: Makro Reiterverweismatrix
05.09.2014 18:12:16
Steffen
Danke Frank!
Die Befehle waren mir noch unbekannt - "programmiere" mit VBA auch erst seit kurzem.
Ich probiere es gleich aus:
Okay - ist etwas schneller aber nur minimal.
Habe eine Beispielexcel angefügt:
https://www.herber.de/bbs/user/92499.zip
Info: Die Suchprozedur ist hier das entscheidende Problem - ich rede hier von einer zu durchsuchenden Excel von über 10 MB Größe.

Anzeige
AW: Makro Reiterverweismatrix
05.09.2014 18:36:20
Steffen
FYI: Das Makro ist nach 23 Minuten durchgelaufen.

AW: Makro Reiterverweismatrix
06.09.2014 00:50:53
Franc
gut - ich hab das mal (komplett) umgeschrieben
wie immer gilt - das Original an nem anderen Ort speichern
Meine Testzeiten waren wie folgt.
1.000.000 Verweise in Blatt 3 (wollte nicht aufteilen, weils aufs gleich rauskommt und da du alle Werte ins Blatt einträgst, sollte er auch nicht viel mehr finden, weil dann das Ende der Spalte erreicht wird)
das Suchmakro hat dafür 136 Sekunden gebraucht (war aber schon optimiert)
das ganze mit der neuen Version dauerte nur noch 24 sek
sollte demnach mindestens 5x schneller sein (oder mehr)
darfst dann gern mal deine Zeiten posten ;-)
ich empfehle dir auch, erstmal das makro anzuschauen und die Kommentare zu lesen
die Formeln kann man sich sparen, weil direkt ausrechnen = Zeitersparnis
anstatt zu suchen wird nun der genutzte Bereich eingelesen und da verglichen - er vergleicht da zwar auch "leere" Zellen aber geht trotzdem schneller
hoffe ich hab deine Formeln richtig umgesetzt
https://www.herber.de/bbs/user/92501.xlsm

Anzeige
AW: Makro Reiterverweismatrix
06.09.2014 00:58:42
Franc
hab grad gesehen das da noch 3 "Testzeilen" drinstehen ^^
a1 = arBereichFormel(i, j)
a2 = arSuche(k)
a3 = InStr(arBereichFormel(i, j), arSuche(k))
diese 3 kannste löschen
die dienten nur zu Fehlersuche, weil ich Depp ersetzen Funktion nutzte ohne nachzudenken und dann bei den Suchbegriffen ein leerzeichen drin war und der dann natürlich nichts mehr gefunden hat ^^

AW: Makro Reiterverweismatrix
08.09.2014 11:52:48
Steffen
Entschuldige die späte Antwort, brauchte ein freies Wochenende =)
So habe 2 Stunden gebraucht, um dein Makro zu 95% zu verstehen ;-)
Aber da ich es verstanden habe kann ich sagen: Klasse! Das hat mein Makro mal eben um Längen geschlagen!
Habe mir gerade ca. 20 deiner Befehle in mein Notizbüchlein geschrieben, für's weitere Leben zum nachschlagen! Top!
Mache mich jetzt ans Feintuning für "die große Mappe".
Eine Frage habe ich zu dem Makro:
If In Str(arBereichFormel(i, j), arSuche(k)) "größer als" 0 Then
...
arErgebnis(z, 5) = Mid(arBereichFormel(i, j), 2, InStrRev(arBereichFormel(i, j), "'") - 2)
arErgebnis(z, 6) = Right(arBereichFormel(i, j), Len(arBereichFormel(i, j)) - InStrRev(arBereichFormel(i, j), "'") - 1)
z = z + 1
das "Exit For" müsste man rausnehmen, falls mehrere Verweise in einer Zelle stehen
Exit For
End If
Da häufig mehrere Verweise in einer Zelle stehen (hab vergessen auch welche in der Beispielexcel zu nutzen) habe ich das Exit for auskommentiert, jedoch so, dass das Arraz folgendes speichert zu dem Wert:
Originalzelle: Reiter2!B10 = '3Reiter'!A1+'3Reiter'!C3 (Wert = 3)
Ausgegeben wird:
Cell: AI; Location: 2Reiter; Value: 3; Auf wen wird verlinkt: '3Reiter'!A1+'3Reiter Zelle: C3
Habe ich den Kommentar falsch verstanden und muss ich noch was dazu anpassen?

Anzeige
AW: Makro Reiterverweismatrix
08.09.2014 11:19:25
Steffen
Entschuldige die späte Antwort, brauchte ein freies Wochenende =)
So habe 2 Stunden gebraucht, um dein Makro zu 95% zu verstehen ;-)
Aber da ich es verstanden habe kann ich sagen: Klasse! Das hat mein Makro mal eben um Längen geschlagen!
Habe mir gerade ca. 20 deiner Befehle in mein Notizbüchlein geschrieben, für's weitere Leben zum nachschlagen! Top!
Mache mich jetzt ans Feintuning für "die große Mappe".
Eine Frage habe ich zu dem Makro:
If In Str(arBereichFormel(i, j), arSuche(k)) "größer als" 0 Then
...
arErgebnis(z, 5) = Mid(arBereichFormel(i, j), 2, InStrRev(arBereichFormel(i, j), "'") - 2)
arErgebnis(z, 6) = Right(arBereichFormel(i, j), Len(arBereichFormel(i, j)) - InStrRev(arBereichFormel(i, j), "'") - 1)
z = z + 1
das "Exit For" müsste man rausnehmen, falls mehrere Verweise in einer Zelle stehen
Exit For
End If
Da häufig mehrere Verweise in einer Zelle stehen (hab vergessen auch welche in der Beispielexcel zu nutzen) habe ich das Exit for auskommentiert, jedoch so, dass das Arraz folgendes speichert zu dem Wert:
Originalzelle: Reiter2!B10 = '3Reiter'!A1+'3Reiter'!C3 (Wert = 3)
Ausgegeben wird:
Cell: AI; Location: 2Reiter; Value: 3; Auf wen wird verlinkt: '3Reiter'!A1+'3Reiter Zelle: C3
Habe ich den Kommentar falsch verstanden und muss ich noch was dazu anpassen?

Anzeige
AW: Makro Reiterverweismatrix
08.09.2014 14:54:37
Steffen
Auch für alle anderen:
Die Suche hat Franc schon extrem gut optimiert (vor allem von der Geschwindigkeit).
Weiß jemand wie man den Fehler, dass bei einem Treffer, nicht nur der erste Verweis in einer Zelle ausgegeben wird, sondern auch die darauf folgenden?

AW: Makro Reiterverweismatrix
08.09.2014 18:05:03
Franc
nicht so schnell - muss auch arbeiten und kann das nur zu Hause machen ;-)
Wie sind denn die neuen Zeiten? (neugierig bin)
alt 23 Minuten
neu = schneller = ? ^^
war doch schwerer als gedacht und sicher umständlicher geschrieben als es sein müsste
Sachen sind in Subs, damit die Formatierung erhalten bleibt
füg das mal als neue Auswertung ein
den alten Teil
Sub alte_auswertung()
If InStr(arBereichFormel(i, j), arSuche(k)) > 0 Then
' wurde der Begriff gefunden, füllen wir das Array
' würde man das Ergebnis direkt eintragen würde es auch wieder ewig dauern
arErgebnis(z, 1) = Replace(Cells(i, j).Address, "$", "")
arErgebnis(z, 2) = Worksheets(a).Name
arErgebnis(z, 3) = arBereichWert(i, j)
arErgebnis(z, 5) = Mid(arBereichFormel(i, j), 2, InStrRev(arBereichFormel(i, j), "'") - 2)
arErgebnis(z, 6) = Right(arBereichFormel(i, j), Len(arBereichFormel(i, j)) - InStrRev( _
arBereichFormel(i, j), "'") - 1)
z = z + 1
' hier verlässt er die Suche und macht mit der nächsten "Zelle" weiter
' das "Exit For" müsste man rausnehmen, falls mehrere Verweise in einer Zelle stehen
Exit For
End If
End Sub
gegen diesen hier (nicht das ganze Makro ersetzen) ^^
Sub neue_auswertung()
If InStr(arBereichFormel(i, j), arSuche(k)) > 0 Then
' wurde der Begriff gefunden, füllen wir das Array
' würde man das Ergebnis direkt eintragen würde es auch wieder ewig dauern
m = 1
Do
' erstes / nächstes Vorkommen von der Suche finden
' m bekommt den Wert von der gefundenen Stelle + Länge vom Suchwort
' m und n haben jetzt die Stelle wo der Zellverweis anfängt
m = InStr(m, arBereichFormel(i, j), arSuche(k)) + Len(arSuche(k))
' brauchen wir weiter unten für den "Startpunkt"
n = m
Do
m = m + 1
'solang m um 1 erhöhen bis die aktuelle Stelle kein Buchstabe ist
'das machen wir auch um das $ Zeichen für absolute Adressen einzubeziehen
Loop While IsNumeric(Mid(arBereichFormel(i, j), m, 1)) = False
Do
'um paar Fehler zu umschiffen prüfen wir ob m kleiner der Länge von der Formel ist
If m < Len(arBereichFormel(i, j)) Then m = m + 1
'wenn die aktuelle Position eine Zahl ist nichts tun
If Mid(arBereichFormel(i, j), m, 1) Like "#" Then
Else
'ist es keine Zahl dann m-1 und do loop verlassen (wollen ja nicht zu viel  _
haben)
m = m - 1
Exit Do
End If
'durchlaufen solang es eine Zahl ist und wir noch nicht am Ende der Formel sind
Loop While IsNumeric(Mid(arBereichFormel(i, j), m, 1)) = True And m <> Len( _
arBereichFormel(i, j))
'Ergebnisse eintragen
'da wir bei A1 anfangen, können wir aus i und j die aktuelle Zelle in A1 Schreibweise  _
ermitteln
arErgebnis(z, 1) = Replace(Cells(i, j).Address, "$", "")
arErgebnis(z, 2) = Worksheets(a).Name
arErgebnis(z, 3) = arBereichWert(i, j)
'auf wen verwiesen wird nehmen wir von der Suche
'da steht zum Beispiel 'Blatt'!
'wir wolle es ab dem 2. Zeichen + Zeichenlänge = Anzahl Zeichen - 2x ' und 1x ! also 3
arErgebnis(z, 5) = Mid(arSuche(k), 2, Len(arSuche(k)) - 3)
'Die Zelle auf die verwiesen wird ist der Startpunkt n
'länge = m - n + 1
arErgebnis(z, 6) = Mid(arBereichFormel(i, j), n, m - n + 1)
z = z + 1
m = m - 1
'solang wiederholen wie er das Suchwort nach dem aktuellen findet
Loop While InStr(m, arBereichFormel(i, j), arSuche(k)) > 0
End If
End Sub

Anzeige
AW: Makro Reiterverweismatrix
09.09.2014 10:40:20
Steffen
Hey Franc,
kann Dir leider keine Auskunft über die Zeiten geben - habe es gerade erst (mit beiden Varianten) an der großen Mappe getestet, um jetzt ernüchterner Weise festzustellen, dass das Makro bei:
  ReDim arErgebnis(1 To lLetzteZeile * lLetzteSpalte, 1 To 6)
Sich aufhängt mit der Fehlermeldung: "Out of memory"
Laut google kann dies der allgemeine Speicher als auch RAM sein. Muss ich noch überprüfen.
Bei kleineren Mappen funktioniert die neue Version bei mir bis bei:
If InStr(arBereichFormel(i, j), arSuche(k)) > 0 Then
Wobei ich diesen Fehler mir zuordne, denn bei der großen Mappe ist das Makro ja "weiter" gekommen.
Ich gehe das Problem für heute von zwei Seiten an:
  • a) Out of memory - Lösung findet damit das Array nicht den Speicher sprengt

  • b) back to the roots: den Suchmechanismus unangetastet lassen und die Ausgabe in der 5. Zeile im Array spliten ("='2Reiter'!A1+Sheet3!B123*'3Reiter'!A2" in die jeweiligen Reiterausgaben (2Reiter / Sheet3 / 3Reiter

  • Mit Split / InStr(Rev) / Search wird es schwierig aufgrund der unterschiedlichen Formatierungen und Rechenzeichen.

    Anzeige
    AW: Makro Reiterverweismatrix
    09.09.2014 13:19:21
    Franc
    mal schnell zwischengefragt
    drück bei der großen Mappe auf strg + Ende und schreib welche Zelle das ist
    hast du etwas in dem Makro geändert?
    Wenn nein, dann sollte es keinen Fehler geben außer es existiert eines der beiden Arrays nicht mehr oder es gibt kein i,j oder k oder einer der genannten Variablen hat einen zu niedrigen (in dem Fall 0, weil beide mit 1 anfangen) oder einen höheren Wert als es Einträge im Array gibt.

    AW: Makro Reiterverweismatrix
    09.09.2014 14:03:38
    Steffen
    Okay der erste Fehler war ein Flüchtigkeitsfehler - Copy+Paste soll gelernt sein.
    Habe das Makro durchlaufen lassen bei "Der Großen" und nach der Fehlermeldung auf "Debug" geklickt und in der Mappe dann Strg+End = XFC458 (gleich im ersten Reiter).
    Run-time error '7':
    Out of memory
    
    Kann es sein, dass wir das Array zu "vollladen"?

    Anzeige
    AW: Makro Reiterverweismatrix
    09.09.2014 14:29:57
    Franc
    Stehen da wirklich noch Daten?
    Das würde bedeuten das da (fast) max. Spaltenanzahl = 16383 genutzt wird.
    Normal zeigt strg + Ende in einer Mappe (dazu muss man die einfach nur offen haben ohne Makros zu starten) die letzte benutze Zelle an. Im Normal ist das dann auch wirklich eine beutzte Zelle bzw. stand da dann schon mal was drin.
    Bis zu welcher Spalte gehen denn die Daten?
    Man kann das ganz aber auch anders lösen.

    AW: Makro Reiterverweismatrix
    09.09.2014 15:23:50
    Steffen
    So bin jetzt mal die "kleine" der beiden Großen manuel durchgegangen (6MB).
    Das Maximum an beschriebenen Zellen in allen Worksheets an Zeilen liegt bei 950 und bei Spalten bei BJ (62. Spalte).
    Die Frage ist hier auch - kann man das dynamisch gestalten?
    Damit das Makro robust und für verschiedenste Mappen gestaltet werden kann.
    Ich messe das an der größeren der beiden Excelmappen. Als mein ursprüngliches Makro dort durchgelaufen ist (ca. 15 Stunden) lag es daran, dass Excel einfach abstürzte.
    Aber das lag eben auch an der extrem uneffizienten Mechanik des Suchlaufs.

    Anzeige
    AW: Makro Reiterverweismatrix
    09.09.2014 14:40:00
    Steffen
    Nebenbei die Verweisausgabe funktioniert nun einwandfrei.
    Habe es auch mit weiteren Trennzeichen probiert: " " & / ^ ;
    Das ist echt klasse!
    FYI:
    ReDim arErgebnis(1 To lLetzteZeile * lLetzteSpalte, 1 To 6)
    lLetzteZeile = 458
    lLetzteSpalte = 16383
    "You can use LONG columns to store a maximum of 16 KB or 16383 characters. "
    Denke mal dieser Speicher ist gemeint mit "Out of Memory"
    Kann man evtl. auch pro Sheet statt pro Workbook oder pro Zelle das Array ausgeben lassen, um das Array nicht zu überfüllen.
    Notiz zum vorherigen Beitrag:
    Zwar ist XFC458 die letzte Zelle des Bereiches - jedoch sind viele nicht beschrieben.

    Anzeige
    AW: Makro Reiterverweismatrix
    09.09.2014 16:37:51
    Franc
    jain - er meint das long ausreichend groß für die Zahl 16.363 ist.
    Byte hat zum Beispiel 1 Byte (und nicht KB ^^) = max. FF = max Anzahl von 255
    wenn ich jetzt zum Beispiel a as byte festlege und a 256 zuweise kommt die Fehlermeldung "Überlauf" = man muss ein größeren Datentyp wählen
    long = 4 Byte = FF FF FF FF = 4.294.967.295 aber 1 bit wird für +- reserviert.
    Glaub FF FF FF FF steht für -2.147.483.648 und FF FF FF FE für +2.147.483.647
    hoff das ist nicht falsch erklärt.
    Gibt auch Variablen die Kommawerte speichern können ect.
    http://de.wikibooks.org/wiki/VBA_in_Excel/_Variablen_und_Arrays
    out of memory heißt aber schlichtweg out of memory ^^
    In dem Fall geht deinem PC der Arbeitsspeicher aus. (er liest den Bereich auch 2x ein)
    Er will 458 * 16383 Zellen einlesen = 7.503.414 Zellen einlesen und das ganze 2x
    Um das trotzdem halbwegs dynamisch zu halten lösche die 2 Zeilen
    lLetzteZeile = Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell).Row
    lLetzteSpalte = Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell).Column
    und schreib dafür das rein - steht wieder in nem subwegen den Tabs
    das mit den Special cells grenzt das ganze erstmal wieder ein
    danach geht er jede Spalte durch und nimmt von der letzten Zeile im Blatt nach oben gesehen die erste befüllte Zeile ... man klingt das doof ^^
    das gleiche mit den Spalten
    Das ist so als wenn du nach ganze rechts gehen würdest (zu Beispiel Zeile 1, Spalte XFD und dann strg + linke Pfeiltaste drückst)
    er macht das für jede Spalte und merkt sich den größten Wert
    sollte jetzt bei Spalte immer noch 16.383 steht bzw. ein viel zu kleiner / großer Wert bedeutet das, das irgendwo in Spalte XFC oder links davon ein Wert vorhanden ist der da eigentlich nicht hingehört.
    Um evtll unsinnige Werte zu löschen kannst du auch manuell die Spalte Rechts von der letzten beschriebenen markieren (spalte ist nun komplett blau hinterlegt) und die Tastenkombi shift + strg + Pfeiltaste nach rechts drücken.
    nun sind alle Spalten rechts markiert und dann Rechtsklick aufs markierte - Zelle löschen.
    Bei sagen wir 100 Spalten x 1000 Zeilen sollte es keine Probleme geben. (sind ja "nur" 100.000 Zellen)
    Sub Zeile_spalte()
    lLetzteZeile = 0
    lLetzteSpalte = 0
    For aktSpalte = 1 To Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell).Column
    If Worksheets(a).Cells(Rows.Count, aktSpalte).End(xlUp).Row > lLetzteZeile Then
    lLetzteZeile = Worksheets(a).Cells(Rows.Count, aktSpalte).End(xlUp).Row
    End If
    Next
    For aktZeile = 1 To Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell).Row
    If Worksheets(a).Cells(aktZeile, Columns.Count).End(xlToLeft).Column > lLetzteSpalte Then
    lLetzteSpalte = Worksheets(a).Cells(aktZeile, Columns.Count).End(xlToLeft).Column
    End If
    Next
    End Sub
    

    AW: Makro Reiterverweismatrix
    09.09.2014 18:07:33
    Steffen
    Danke Franc für die ganze Mühe die du Dir machst!
    Werde morgen das Ganze ausprobieren - heute "schiebe ich eine ruhige Kugel"
    Billard

    AW: Makro Reiterverweismatrix
    09.09.2014 18:13:17
    Franc
    gut - schreib bei Erfolg auch bitte die Zeiten rein. ;-)

    AW: Makro Reiterverweismatrix
    10.09.2014 12:02:26
    Steffen
    Hallo Franc,
    so frisch und erholt nochmal ans Werk und nochmal 2 Bugs gefunden, ABER:
    Konnte Sie soweit lösen.
    FYI:
    Habe im Reiter SheetSearchList den Befehl
    Sub Test()
    .Cells(i - 1, 1) = "'" & Worksheets(i).Name & "'!"
    arSuche(i - 2) = "'" & Worksheets(i).Name & "!'" ' Suchbegriffe eintragen
    End Sub
    
    umgewandet. Ich musste die ' und ! entfernen, da bei einem Reiter ohne Sonderzeichen am Anfang (z.B.: Sheet3 diese nicht eingefügt werden müssen, dass Makro aber so nach 'Sheet3'! sucht.
    Dementsprechend habe ich auch die Ausgabe angepasst
    Sub Ergebnis
    arErgebnis(z, 5) = Mid(arSuche(k), 2, Len(arSuche(k))-3)
    End Sub
    

    da kein ' am Anfang und '! am Ende steht.
    Das selbe muss ich noch für das Ergebnis in der 6. Spalte des Arrays anpassen. Das wird schwierig da die Reiter unterschiedlich lang sind.
    Jetzt kommt das worauf wir alle gewartet haben - der große Test: (ja ich schreibe in Echtzeit)
    Das Makro läuft 10,7 Sekunden, schreibt dabei 4091 Treffer auf und durchsucht 20 Reiter.
    Beendet wird das Makro durch ein:
    Subscript out of Range in der Zeile: arErgebnis(z, 1) = Replace(Cells(i, j).Address, "$", "")
    z = 3751
    Ich denke bei z und dem Array muss der Fehler liegen.
    Die Zelle/Formel/usw. habe ich soweit nach Bugs untersucht:
    m = 229 in: 'Steffen Sheep'!$E$28
    n = 223 in: 'Steffen Sheep'!$E$28
    i = 29
    j = 1
    Die Formel in U29, die gerade durchsucht wir ist:(Reiter umbenannt, jedoch Zeichenanzahl für jeden Reiter identisch)
    k = 5
    arSuche(k) = "Steffen Sheep"
    Sub Formel
    ='Arzt Afterhour AH, @m'!U29*'Steffen Sheep'!$E$24+'Absturz Aasfresser'!U29*'Steffen Sheep'!$E$ _
    25
    +'Aufrisszone Umgangsform'!U29*'Steffen Sheep'!$E$26+Afterhour!U29*'Steffen Sheep'!$E$27+'Bus  _
    Umgangsform'!U29
    *'Steffen Sheep'!$E$28+Augenpflege!U29*'Steffen Sheep'!$E$29+'Auto Umgangsform'!U29*'Steffen  _
    Sheep'!$E$30
    +'Umgangsall Meppen 1'!U29*'Steffen Sheep'!$E$33+'ABC Umgangsform'!U29*'Steffen Sheep'!$E$31
    +'Aerztin Steppen Umgangsform'!U29*'Steffen Sheep'!$E$32+'Umgangsall Meppen 2'!U29*'Steffen  _
    Sheep'!$E$34
    +'Umgangsall Meppen 3'!U29*'Steffen Sheep'!$E$35+'Umgangsall Meppen 4'!U29*'Steffen Sheep'!$E$ _
    36
    End Sub
    
    Info: Die Zellen links von dieser beinhalten die selbe Formel mit verschobenen Verweisen, dort jedoch anscheinend kein Fehler.

    AW: Makro Reiterverweismatrix
    10.09.2014 17:10:39
    Franc
    Hmm - könnte mir grad nicht erklären, warum er grad an der Stelle diese Fehler bringt.
    Wäre z höher als die Anzahl möglicher Einträge würde es ein Überlauffehler geben.
    die Zeile selbst macht nur folgendes
    Replace(Cells(i, j).Address, "$", "")
    cells(i = 1, j = 29).Address =$A$29 und durch das Replace wird das zu A29
    Das wird dann dem Array arErgebnis(z=3751, 1) zugewiesen
    Das kann eigentlich gar nicht auf Fehler laufen.
    Hast du im Editor unten die "Lokal" Ansicht? Wenn nein aktiviere sie unter "Ansicht" - "Lokal"
    Wenn er an der Stelle stoppt siehst du unten alle Variablen aus dem Modul (aber keine globalen Variablen - falls du was ergänzt hat)
    klick bei arErgebnis auf das "+" zeichen und scrolle mal runter und schau nach ob der entsprechende Eintrag vefügbar ist.
    Test auch mal ob der Fehler auftritt, wenn du
    arErgebnis(z, 5) = arErgebnis(z, 1) = Replace(Cells(i, j).Address, "$", "")
    durch
    xyz = Replace(Cells(i, j).Address, "$", "")
    ersetzt. (dann fehlt zwar im Blatt erstmal eine Angabe aber nur mal so zum schauen.)
    Kann auch an was anderem liegen aber dazu solltest du noch mal das gesamte Makro posten wie es bei dir aktuell in der Mappe steht.

    AW: Makro Reiterverweismatrix
    10.09.2014 18:51:28
    Steffen
    arErgebnis für z=3751 ist nicht vorhanden.
    Für 3750:
    arErgebnis(3750,1/2/3/4/5/6) = U29/Reiter/0/Empty/"Steffen Sheep"/"!$E$27"
    Habe:
    arErgebnis(z, 1) = ... & arErgebnis(z, 5) = ...
    durch
    xyz = Replace(Cells(i, j).Address, "$", "")
    ersetzt.
    Selber Fehler bei
    arErgebnis(z, 2) = Worksheets(a).Name (und auch kein Eintrag im Local)
    Nochmal das gesamte Skript (habe eig. nur das Speichern abgeändert):
     Sub Hirn2()
    Dim a As Integer, i As Long, j As Long, k As Integer, z As Long, gespeichert As Integer
    Dim arBereichFormel As Variant, arBereichWert As Variant, arSuche As Variant, arErgebnis As  _
    Variant
    Dim strBereich As String, lLetzteZeile As Long, lLetzteSpalte As Long, strFilename As String
    ' Speicherdialog
    Application.DisplayAlerts = False
    ChDrive "c:\temp\"
    strFilename = "SheetLinksMatrixOverview" & Format(Date, "yyyymmdd") & ".xlsx"
    Application.Dialogs(xlDialogSaveAs).Show (strFilename)
    Application.DisplayAlerts = False
    strFilename = ActiveWorkbook.Name
    Application.Calculation = xlCalculationManual ' automat. Berechnung ausschalten
    Application.ScreenUpdating = False ' Bildschirmaktualisierung ausschalten
    Application.DisplayAlerts = False ' er fragt nicht nach beim löschen der Blätter
    For i = Worksheets.Count To 1 Step -1
    Worksheets(i).Visible = xlSheetVisible
    If Worksheets(i).Name = "SheetMatrixOverview" Then Worksheets(i).Delete
    If Worksheets(i).Name = "SheetSearchList" Then Worksheets(i).Delete
    Next
    Application.DisplayAlerts = True
    ' suche dimensionieren = Anzahl Tabellenblätter (aktuell ja noch ohne die 2 ersten)
    ReDim arSuche(1 To Worksheets.Count)
    ' Blätter hinzufügen
    Worksheets.Add Before:=Worksheets(1)
    ActiveSheet.Name = "SheetMatrixOverview"
    Worksheets.Add after:=Worksheets(1)
    ActiveSheet.Name = "SheetSearchList"
    ' Blatt formatieren
    With Worksheets("SheetSearchList")
    .Cells(1, 1) = "Suchbegriffe:"
    .Cells(1, 3) = "Cell:"
    .Cells(1, 4) = "Location:"
    .Cells(1, 5) = "Value:"
    .Cells(1, 7) = "Auf wen wird verlinkt:"
    For i = 3 To Worksheets.Count ' vom 3. bis letzten Blatt
    .Cells(i - 1, 1) = Worksheets(i).Name
    arSuche(i - 2) = Worksheets(i).Name ' Suchbegriffe eintragen
    Next
    End With
    For a = 3 To Worksheets.Count ' vom 3. bis letzten Blatt
    z = 1 ' z ist für das Ergebnisarray
    Worksheets(a).Activate ' das muss aktiv sein, weil sonst weiter unten keine Formeln  _
    eingelesen werden
    lLetzteZeile = 0
    lLetzteSpalte = 0
    For aktSpalte = 1 To Worksheets(a).UsedRange.SpecialCells( _
    xlCellTypeLastCell).Column
    If Worksheets(a).Cells(Rows.Count, aktSpalte).End(xlUp).Row >  _
    lLetzteZeile Then
    lLetzteZeile = Worksheets(a).Cells(Rows.Count, aktSpalte).End(xlUp). _
    Row
    End If
    Next
    For aktZeile = 1 To Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell) _
    .Row
    If Worksheets(a).Cells(aktZeile, Columns.Count).End(xlToLeft).Column >  _
    lLetzteSpalte Then
    lLetzteSpalte = Worksheets(a).Cells(aktZeile, Columns.Count).End( _
    xlToLeft).Column
    End If
    Next
    ' Geht immer von A1 bis letzte Zelle
    strBereich = "$A$1:" & Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell).Address
    ' falls keine oder nur eine beschrieben sind geben wir ihm die ersten 2 vor
    ' tun wir das nicht, läuft es auf Fehler, weil das Array nicht befüllt wird
    If lLetzteSpalte = 1 And lLetzteZeile = 1 Then strBereich = "A1:B2"
    ' hier kommen 2 Arrays vom genutzten Bereich
    ' die Formeln
    arBereichFormel = range(strBereich).Formula
    ' die Werte die drin stehen
    arBereichWert = range(strBereich)
    ' Ergebnis Array anpassen, Anzahl Einträge = Letzte Zeile * letzte Spalte und das Array hat  _
    6 "Spalten"
    ReDim arErgebnis(1 To lLetzteZeile * lLetzteSpalte, 1 To 6)
    ' jetzt schaut er in jeden Eintrag vom Array nach
    For i = 1 To lLetzteZeile
    For j = 1 To lLetzteSpalte
    ' prüfen ob es eine Formel ist (spart Zeit wenn nicht)
    If InStr(arBereichFormel(i, j), "=") > 0 Then
    ' schauen ob der Suchbegriff vorkommt - dazu prüft er direkt jeden Suchbegriff
    For k = 1 To UBound(arSuche) ' ubound = Nr. vom letzten Eintrag
    If InStr(arBereichFormel(i, j), arSuche(k)) > 0 Then
    ' wurde der Begriff gefunden, füllen wir das Array
    ' würde man das Ergebnis direkt eintragen würde es auch wieder ewig  _
    dauern
    m = 1
    Do
    ' erstes / nächstes Vorkommen von der Suche finden
    ' m bekommt den Wert von der gefundenen Stelle + Länge vom Suchwort
    ' m und n haben jetzt die Stelle wo der Zellverweis anfängt
    m = InStr(m, arBereichFormel(i, j), arSuche(k)) + Len(arSuche(k))
    ' brauchen wir weiter unten für den "Startpunkt"
    n = m
    Do
    m = m + 1
    'solang m um 1 erhöhen bis die aktuelle Stelle kein Buchstabe  _
    ist
    'das machen wir auch um das $ Zeichen für absolute Adressen  _
    einzubeziehen
    Loop While IsNumeric(Mid(arBereichFormel(i, j), m, 1)) = False
    Do
    'um paar Fehler zu umschiffen prüfen wir ob m kleiner der Länge  _
    von der Formel ist
    If m < Len(arBereichFormel(i, j)) Then m = m + 1
    'wenn die aktuelle Position eine Zahl ist nichts tun
    If Mid(arBereichFormel(i, j), m, 1) Like "#" Then
    Else
    'ist es keine Zahl dann m-1 und do loop verlassen (wollen  _
    ja nicht zu viel _
    haben)
    m = m - 1
    Exit Do
    End If
    'durchlaufen solang es eine Zahl ist und wir noch nicht am Ende  _
    der Formel sind
    Loop While IsNumeric(Mid(arBereichFormel(i, j), m, 1)) = True And m  _
    <> Len( _
    arBereichFormel(i, j))
    'Ergebnisse eintragen
    'da wir bei A1 anfangen, können wir aus i und j die aktuelle Zelle  _
    in A1 Schreibweise _
    ermitteln
    xyz = Replace(Cells(i, j).Address, "$", "")
    arErgebnis(z, 2) = Worksheets(a).Name
    arErgebnis(z, 3) = arBereichWert(i, j)
    'auf wen verwiesen wird nehmen wir von der Suche
    'da steht zum Beispiel 'Blatt'!
    'wir wolle es ab dem 2. Zeichen + Zeichenlänge = Anzahl Zeichen -  _
    2x ' und 1x ! also 3
    xyz = Replace(Cells(i, j).Address, "$", "")
    'Die Zelle auf die verwiesen wird ist der Startpunkt n
    'länge = m - n + 1
    arErgebnis(z, 6) = Mid(arBereichFormel(i, j), n, m - n + 1)
    z = z + 1
    m = m - 1
    'solang wiederholen wie er das Suchwort nach dem aktuellen findet
    Loop While InStr(m, arBereichFormel(i, j), arSuche(k)) > 0
    End If
    Next
    End If
    Next
    Next
    ' er hats das Blatt durchgeackert und wenn mindestens 1 Ergebnis vorliegt, trägt er es ein
    If z <> 1 Then
    ' nächste freie Zeile suchen
    lLetzteZeile = Sheets("SheetSearchList").Cells(Rows.Count, 3).End(xlUp).Row + 1
    ' das gesamte Array ins Blatt eintragen
    Worksheets("SheetSearchList").Cells(lLetzteZeile, 3).Resize(z - 1, 6).Value =  _
    arErgebnis
    End If
    ' wiederholen bis alle Blätter durch sind
    Next
    ' arrays löschen
    Erase arBereichFormel
    Erase arBereichWert
    Erase arErgebnis
    ' 1. Blatt aktivieren
    Sheets("SheetMatrixOverview").Activate
    Cells(1, 1).Value = "Matrix:"
    For i = 3 To Worksheets.Count
    Cells(i - 1, 1).Value = Worksheets(i).Name
    Cells(1, i - 1).Value = Worksheets(i).Name
    Next
    ' wir berechnen das direkt in VBA ohne Umweg
    lLetzteZeile = Sheets("SheetSearchList").Cells(Rows.Count, 3).End(xlUp).Row
    For i = 3 To Worksheets.Count
    For j = 3 To Worksheets.Count
    Cells(i - 1, j - 1).Value = Application.WorksheetFunction.CountIfs(Sheets(" _
    SheetSearchList").range("D2:D" & lLetzteZeile), Worksheets(i).Name, Sheets("SheetSearchList").range("G2:G" & lLetzteZeile), Worksheets(j).Name)
    Next
    Next
    ' alles wieder einschalten
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Exit Sub
    Error:
    Erase arBereichFormel
    Erase arBereichWert
    Erase arErgebnis
    Application.Calculation = xlCalculationAutomatic ' automat.Berechnung einschalten falls ein  _
    Fehler ausgegeben wird
    MsgBox ("Error 404 - Page not Found")
    End Sub
    
    Local Eintrag:
    a = 21; i = 29; j = 21; k = 4; z= 3751; gespeichert = 0; strBereich "$A$1:$AE$322"; lLetzteZeile = 125; lLetzteSpalte = 30; aktSpalte = 32; aktZeile = 323; m = 229; 2 = 223; xyz = "U29"

    AW: Makro Reiterverweismatrix
    11.09.2014 16:34:20
    Franc
    omg - seh wieder den Wald vor lauter Bäumen nicht ^^
    müsste damit gehen und bin dann mal auf finalen Benchmark gespannt. ^^
    grad wollte ich erklären warum z nicht zu klein sein kann und ja ... natürlich kann z zu klein werden, weil wenn im Schnitt in jeder Zelle mehr als ein Verweis steht dann wird z zu klein. (ich war gedanklich immer noch beim Schema wo eine Zelle nur 1 Wert liefern kann
    nimm mal das
    ReDim arErgebnis(1 To lLetzteZeile * lLetzteSpalte * 10, 1 To 6)
    dann wäre Platz für (aktuelles Beispiel)
    lLetzteSpalte = 30 * lLetzteZeile = 125 * 10 = 37.500 Einträge
    Das sollte vollkommen langen, wir verschwenden nicht zu viel Platz und ersparen und redim preserve Orgien. Wirst ja kaum im Schnitt mehr als 10 Verweise pro Zelle haben.
    Ergänze auch folgende Zeile.
    Die kommt nach den 2 for Schleifen und vor diese Zeile (NICHT ersetzen ^^)
    "If InStr(arBereichFormel(i, j), "=") "kleiner" 0 Then"
    arBereichFormel(i, j) = Replace(Replace(arBereichFormel(i, j), "'", ""), "!", "")
    Damit ersetzt er etwaige ' und ! in er Formel durch nichts und es sollte keine Probleme dabei geben den Bereich zu ermittel worauf verwiesen wird.
    Das Sucharray selbst wird ja so oder so nur mit den Blattnamen ohne ' oder ! befüllt.
    Die Änderungen finden auch nur im Array statt und haben keine Auswirkung auf das Arbeitsblatt.
    Mir fällt noch folgendes auf
    strg + Ende führt bei dir wahrscheinlich bei dem Blatt zur Zelle AF323 obwohl das eigentlich AD125 sein müsste.Evtll mal den Rest"löschen"?
    Rechts neben die letzte benutzte Spalte zum Beispiel AG1 klicken, strg + shift + ende gefolgt von rechtsklick, Zellen löschen, ganze Spalte löschen
    und dann noch mal in A126? und da auch strg + shift + ende, zellen löschen, ganze Zeile löschen
    Mappe speichern, schließen, neu öffnen und dann solltestrg + ende AD125 sein. (wenn sich bis dahin nichts ändert ^^)

    AW: Makro Reiterverweismatrix
    12.09.2014 18:35:08
    Steffen
    Hallo Franc,
    ein weiteres DANKE FRANC, wir sind wieder ein großes Stück weiter gekommen.
    wir haben unser Ergebnis versechsfacht in 18,9 Sekunden haben wir 23809 Treffer eingetragen.
    WOHOO!! ERFOLG!
    (im Array sind laut LocalView jetzt 24380 Treffer - Aber komischerweise sind viele davon einfach Empty - ab dem 600.)
    Fehler tritt auf: Out of Memory
    arBereichFormel = range(strBereich).Formula
    range(strBereich).Formula =
    strBereich ist "$A$1:$XFC$942 (also wieder unser strg + ende Problem)
    a 26
    i 54
    j 47
    k 73
    z 1
    lLetzteZeile 942, lLetzteSpalte 48
    aktSpalte 16384
    aktZeile 943
    m 22
    n 18
    länge 6
    Lösungsversuche:
    1. Überflüssige Spalten löschen, von WErten und Formaten "befreien"
    2. "Freeze Panes" (Deutsch soetwas wie: eingefrorene Bereiche) "auftauen" ;-)
    gespeichert und neugestartet
    Seitdem immer Makroabsturz.
    1. Habe alle 72 (ist k = 73 so richtig, da die erste Zeile mit: Suchbegriffe mitgezähltz wird?)Reiter nach Ihren maximalen Spalten und Zeilen durchforstet und diese dann manuel eingegeben.
    Das Makro läuft dann (da nicht dynamisch) ca 15 Minuten und gibt eine Fehlermeldung aus, die jedoch dank sofortigem Absturz nicht lesbar ist. (Strg + Pause bewirkt das selbe)
    Weiterhin aufgetretener Fehler:
    In Zeilen mit 'Reiter'!#REF durchsucht das Makro bis zu locker 10000000 Stellen nach dem Beginn der nächsten Adresse. Bei einer Formel die nichtmal so lang ist (=IFERROR(AE12/'Surf Dezember AH, %?'!#REF!;"N/M").
    Hier nochmal das Makro auf dem neusten Stand:
    
    Sub Hirn3()
    Dim a As Integer, i As Long, j As Long, k As Integer, z As Long, gespeichert As Integer
    Dim arBereichFormel As Variant, arBereichWert As Variant, arSuche As Variant, arErgebnis As  _
    Variant
    Dim strBereich As String, lLetzteZeile As Long, lLetzteSpalte As Long, strFilename As String
    ' Speicherdialog
    Application.DisplayAlerts = False
    ChDrive "c:\temp\"
    strFilename = "SheetLinksMatrixOverview" & Format(Date, "yyyymmdd") & ".xlsx"
    Application.Dialogs(xlDialogSaveAs).Show (strFilename)
    Application.DisplayAlerts = False
    strFilename = ActiveWorkbook.Name
    Application.Calculation = xlCalculationManual ' automat. Berechnung ausschalten
    Application.ScreenUpdating = False ' Bildschirmaktualisierung ausschalten
    Application.DisplayAlerts = False ' er fragt nicht nach beim löschen der Blätter
    For i = Worksheets.Count To 1 Step -1
    Worksheets(i).Visible = xlSheetVisible
    If Worksheets(i).Name = "SheetMatrixOverview" Then Worksheets(i).Delete
    If Worksheets(i).Name = "SheetSearchList" Then Worksheets(i).Delete
    Next
    Application.DisplayAlerts = True
    ' suche dimensionieren = Anzahl Tabellenblätter (aktuell ja noch ohne die 2 ersten)
    ReDim arSuche(1 To Worksheets.Count)
    ' Blätter hinzufügen
    Worksheets.Add Before:=Worksheets(1)
    ActiveSheet.Name = "SheetMatrixOverview"
    Worksheets.Add after:=Worksheets(1)
    ActiveSheet.Name = "SheetSearchList"
    ' Blatt formatieren
    With Worksheets("SheetSearchList")
    .Cells(1, 1) = "Suchbegriffe:"
    .Cells(1, 3) = "Cell:"
    .Cells(1, 4) = "Location:"
    .Cells(1, 5) = "Value:"
    .Cells(1, 7) = "Auf wen wird verlinkt:"
    For i = 3 To Worksheets.Count ' vom 3. bis letzten Blatt
    .Cells(i - 1, 1) = Worksheets(i).Name
    arSuche(i - 2) = Worksheets(i).Name ' Suchbegriffe eintragen
    Next
    End With
    For a = 3 To Worksheets.Count ' vom 3. bis letzten Blatt
    z = 1 ' z ist für das Ergebnisarray
    Worksheets(a).Activate ' das muss aktiv sein, weil sonst weiter unten keine Formeln  _
    eingelesen werden
    lLetzteZeile = 0
    lLetzteSpalte = 0
    For aktSpalte = 1 To Worksheets(a).UsedRange.SpecialCells( _
    xlCellTypeLastCell).Column
    If Worksheets(a).Cells(Rows.Count, aktSpalte).End(xlUp).Row >  _
    lLetzteZeile Then
    lLetzteZeile = Worksheets(a).Cells(Rows.Count, aktSpalte).End(xlUp). _
    Row
    End If
    Next
    For aktZeile = 1 To Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell) _
    .Row
    If Worksheets(a).Cells(aktZeile, Columns.Count).End(xlToLeft).Column >  _
    lLetzteSpalte Then
    lLetzteSpalte = Worksheets(a).Cells(aktZeile, Columns.Count).End( _
    xlToLeft).Column
    End If
    Next
    ' Geht immer von A1 bis letzte Zelle
    strBereich = "$A$1:" & Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell).Address
    ' falls keine oder nur eine beschrieben sind geben wir ihm die ersten 2 vor
    ' tun wir das nicht, läuft es auf Fehler, weil das Array nicht befüllt wird
    If lLetzteSpalte = 1 And lLetzteZeile = 1 Then strBereich = "A1:B2"
    ' hier kommen 2 Arrays vom genutzten Bereich
    ' die Formeln
    arBereichFormel = range(strBereich).Formula
    ' die Werte die drin stehen
    arBereichWert = range(strBereich)
    ' Ergebnis Array anpassen, Anzahl Einträge = Letzte Zeile * letzte Spalte und das Array hat  _
    6 "Spalten"
    ReDim arErgebnis(1 To lLetzteZeile * lLetzteSpalte * 10, 1 To 6) ' 10 = durschnittliche  _
    Verweise pro Zelle als Kennzahl für die Speicherkapatität des Arrays
    ' jetzt schaut er in jeden Eintrag vom Array nach
    For i = 1 To lLetzteZeile
    For j = 1 To lLetzteSpalte
    arBereichFormel(i, j) = Replace(Replace(arBereichFormel(i, j), "'", ""), "!", "")
    ' prüfen ob es eine Formel ist (spart Zeit wenn nicht)
    If InStr(arBereichFormel(i, j), "=") > 0 Then
    ' schauen ob der Suchbegriff vorkommt - dazu prüft er direkt jeden Suchbegriff
    For k = 1 To UBound(arSuche) ' ubound = Nr. vom letzten Eintrag
    If InStr(arBereichFormel(i, j), arSuche(k)) > 0 Then
    ' wurde der Begriff gefunden, füllen wir das Array
    ' würde man das Ergebnis direkt eintragen würde es auch wieder ewig  _
    dauern
    m = 1
    Do
    ' erstes / nächstes Vorkommen von der Suche finden
    ' m bekommt den Wert von der gefundenen Stelle + Länge vom Suchwort
    ' m und n haben jetzt die Stelle wo der Zellverweis anfängt
    m = InStr(m, arBereichFormel(i, j), arSuche(k)) + Len(arSuche(k))
    ' brauchen wir weiter unten für den "Startpunkt"
    n = m
    Do
    m = m + 1
    'solang m um 1 erhöhen bis die aktuelle Stelle kein Buchstabe  _
    ist
    'das machen wir auch um das $ Zeichen für absolute Adressen  _
    einzubeziehen
    Loop While IsNumeric(Mid(arBereichFormel(i, j), m, 1)) = False
    Do
    'um paar Fehler zu umschiffen prüfen wir ob m kleiner der Länge  _
    von der Formel ist
    If m < Len(arBereichFormel(i, j)) Then m = m + 1
    'wenn die aktuelle Position eine Zahl ist nichts tun
    If Mid(arBereichFormel(i, j), m, 1) Like "#" Then
    Else
    'ist es keine Zahl dann m-1 und do loop verlassen (wollen  _
    ja nicht zu viel _
    haben)
    m = m - 1
    Exit Do
    End If
    'durchlaufen solang es eine Zahl ist und wir noch nicht am Ende  _
    der Formel sind
    Loop While IsNumeric(Mid(arBereichFormel(i, j), m, 1)) = True And m  _
    <> Len( _
    arBereichFormel(i, j))
    'Ergebnisse eintragen
    'da wir bei A1 anfangen, können wir aus i und j die aktuelle Zelle  _
    in A1 Schreibweise _
    ermitteln
    'On Error GoTo Fehler
    arErgebnis(z, 1) = Replace(Cells(i, j).Address, "$", "")
    arErgebnis(z, 2) = Worksheets(a).Name
    arErgebnis(z, 3) = arBereichWert(i, j)
    'auf wen verwiesen wird nehmen wir von der Suche
    'da steht zum Beispiel 'Blatt'!
    'wir wolle es ab dem 2. Zeichen + Zeichenlänge = Anzahl Zeichen -  _
    2x ' und 1x ! also 3
    arErgebnis(z, 5) = Mid(arSuche(k), 1, Len(arSuche(k)) - 1)
    'Die Zelle auf die verwiesen wird ist der Startpunkt n
    länge = m - n + 1
    arErgebnis(z, 6) = Mid(arBereichFormel(i, j), n, m - n + 1)
    'Fehler:
    z = z + 1
    m = m - 1
    'solang wiederholen wie er das Suchwort nach dem aktuellen findet
    Loop While InStr(m, arBereichFormel(i, j), arSuche(k)) > 0
    End If
    Next
    End If
    Next
    Next
    ' er hats das Blatt durchgeackert und wenn mindestens 1 Ergebnis vorliegt, trägt er es ein
    If z <> 1 Then
    ' nächste freie Zeile suchen
    lLetzteZeile = Sheets("SheetSearchList").Cells(Rows.Count, 3).End(xlUp).Row + 1
    ' das gesamte Array ins Blatt eintragen
    Worksheets("SheetSearchList").Cells(lLetzteZeile, 3).Resize(z - 1, 6).Value =  _
    arErgebnis
    End If
    ' wiederholen bis alle Blätter durch sind
    Next
    ' arrays löschen
    Erase arBereichFormel
    Erase arBereichWert
    Erase arErgebnis
    ' 1. Blatt aktivieren
    Sheets("SheetMatrixOverview").Activate
    Cells(1, 1).Value = "Matrix:"
    For i = 3 To Worksheets.Count
    Cells(i - 1, 1).Value = Worksheets(i).Name
    Cells(1, i - 1).Value = Worksheets(i).Name
    Next
    ' wir berechnen das direkt in VBA ohne Umweg
    lLetzteZeile = Sheets("SheetSearchList").Cells(Rows.Count, 3).End(xlUp).Row
    For i = 3 To Worksheets.Count
    For j = 3 To Worksheets.Count
    Cells(i - 1, j - 1).Value = Application.WorksheetFunction.CountIfs(Sheets(" _
    SheetSearchList").range("D2:D" & lLetzteZeile), Worksheets(i).Name, Sheets("SheetSearchList").range("G2:G" & lLetzteZeile), Worksheets(j).Name)
    Next
    Next
    ' alles wieder einschalten
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Exit Sub
    Error:
    Erase arBereichFormel
    Erase arBereichWert
    Erase arErgebnis
    Application.Calculation = xlCalculationAutomatic ' automat.Berechnung einschalten falls ein  _
    Fehler ausgegeben wird
    MsgBox ("Error 404 - Page not Found")
    End Sub
    
    Info:
    Kann Dir am Wochenende leider nicht sicher antworten, da ich in eine neue Wohnung ohne Internetzugang ziehe.
    Versuche aber anderweitig weiterhin auf dem laufenden sein zu können.
    Ich hoffe du bist dieses Makros noch nicht überdrüssig sondern freust dich über jeden weiteren Wert der ausgegeben wird, denn ich werde nicht aufgeben, weil es mein Speicher tut!

    AW: Makro Reiterverweismatrix
    16.09.2014 19:34:09
    Steffen
    So es gibt neue Ergebnisse:
    Die kleinere Mappe rattert er durch in ca. 50 Sekunden trägt das Makro 30830 Werte ein und erstellt dazu die Matrix.
    Behobene Fehler: Manuelles Rauslöschen des Strg + Ende Berereiches der bis XFC oder zurr maximalen Zeile ging. Der Fehler, dass danach das Makro sich aufhing lag daran, dass ein neuer Bug eine unendlich Schleife erzeugte durch eine Zelle mit dem Inhalt: ='Reiter'!#Ref da die Loop Isnumeric bis zur maximalen Stelle innerhalb der Zelle suchte (nebenbei: 1073741825).
    Durch ein eingefügtes
    If m > Länge der Zelle Exit Do
    ließ sich dies beheben.
    Jetzt bearbeite ich die Bugs an der großen Mappe und hoffe auf weitere Werte.
    Bug:
    Zelle mit einem Kommentar: '=-12,8 (Reiter2) -69,0(ABC) - 999,9 (ABC3)
    Die Suchengine findet den Reiter "Reiter2". Kann jedoch den Rest nicht zuordnen.
    Fehlermeldung: Application-defined or object-defined error
    Problem:
    a 12; i 224; j 46; k 190, z 695; lLetzteZeile 8471; lLetzteSpalte 45; aktSpalte 46; aktZeile 243; m 79; n 75; länge 6
    arSuche = Subscript out of Range (k=190 - bei 189 Reitern)
    arBereichFormel = Subscript out of Range
    strBereich $A$1:$AS$242
    arErgebnis = empty
    Hier der aktuelle Code:
    
    Sub Hirn2()
    Dim a As Integer, i As Long, j As Long, k As Integer, z As Long, gespeichert As Integer
    Dim arBereichFormel As Variant, arBereichWert As Variant, arSuche As Variant, arErgebnis As  _
    Variant
    Dim strBereich As String, lLetzteZeile As Long, lLetzteSpalte As Long, strFilename As String
    ' Speicherdialog
    Application.DisplayAlerts = False
    ChDrive "c:\temp\"
    strFilename = "SheetLinksMatrixOverview" & Format(Date, "yyyymmdd") & ".xlsx"
    Application.Dialogs(xlDialogSaveAs).Show (strFilename)
    Application.DisplayAlerts = False
    strFilename = ActiveWorkbook.Name
    Application.Calculation = xlCalculationManual ' automat. Berechnung ausschalten
    Application.ScreenUpdating = False ' Bildschirmaktualisierung ausschalten
    Application.DisplayAlerts = False ' er fragt nicht nach beim löschen der Blätter
    For i = Worksheets.Count To 1 Step -1
    Worksheets(i).Visible = xlSheetVisible
    If Worksheets(i).Name = "SheetMatrixOverview" Then Worksheets(i).Delete
    If Worksheets(i).Name = "SheetSearchList" Then Worksheets(i).Delete
    Next
    Application.DisplayAlerts = True
    ' suche dimensionieren = Anzahl Tabellenblätter (aktuell ja noch ohne die 2 ersten)
    ReDim arSuche(1 To Worksheets.Count)
    ' Blätter hinzufügen
    Worksheets.Add Before:=Worksheets(1)
    ActiveSheet.Name = "SheetMatrixOverview"
    Worksheets.Add after:=Worksheets(1)
    ActiveSheet.Name = "SheetSearchList"
    ' Blatt formatieren
    With Worksheets("SheetSearchList")
    .Cells(1, 1) = "Suchbegriffe:"
    .Cells(1, 3) = "Cell:"
    .Cells(1, 4) = "Location:"
    .Cells(1, 5) = "Value:"
    .Cells(1, 7) = "Auf wen wird verlinkt:"
    For i = 3 To Worksheets.Count ' vom 3. bis letzten Blatt
    .Cells(i - 1, 1) = Worksheets(i).Name
    arSuche(i - 2) = Worksheets(i).Name ' Suchbegriffe eintragen
    Next
    End With
    For a = 3 To Worksheets.Count ' vom 3. bis letzten Blatt
    z = 1 ' z ist für das Ergebnisarray
    Worksheets(a).Activate ' das muss aktiv sein, weil sonst weiter unten keine Formeln  _
    eingelesen werden
    lLetzteZeile = 0
    lLetzteSpalte = 0
    For aktSpalte = 1 To Worksheets(a).UsedRange.SpecialCells( _
    xlCellTypeLastCell).Column
    If Worksheets(a).Cells(Rows.Count, aktSpalte).End(xlUp).Row >  _
    lLetzteZeile Then
    lLetzteZeile = Worksheets(a).Cells(Rows.Count, aktSpalte).End(xlUp). _
    Row
    End If
    Next
    For aktZeile = 1 To Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell) _
    .Row
    If Worksheets(a).Cells(aktZeile, Columns.Count).End(xlToLeft).Column >  _
    lLetzteSpalte Then
    lLetzteSpalte = Worksheets(a).Cells(aktZeile, Columns.Count).End( _
    xlToLeft).Column
    End If
    Next
    ' Geht immer von A1 bis letzte Zelle
    strBereich = "$A$1:" & Worksheets(a).UsedRange.SpecialCells(xlCellTypeLastCell).Address
    ' falls keine oder nur eine beschrieben sind geben wir ihm die ersten 2 vor
    ' tun wir das nicht, läuft es auf Fehler, weil das Array nicht befüllt wird
    If lLetzteSpalte = 1 And lLetzteZeile = 1 Then strBereich = "A1:B2"
    ' hier kommen 2 Arrays vom genutzten Bereich
    ' die Formeln
    arBereichFormel = range(strBereich).Formula
    ' die Werte die drin stehen
    arBereichWert = range(strBereich)
    ' Ergebnis Array anpassen, Anzahl Einträge = Letzte Zeile * letzte Spalte und das Array hat  _
    6 "Spalten"
    ReDim arErgebnis(1 To lLetzteZeile * lLetzteSpalte * 5, 1 To 6) ' 10 = durschnittliche  _
    Verweise pro Zelle als Kennzahl für die Speicherkapatität des Arrays
    ' jetzt schaut er in jeden Eintrag vom Array nach
    For i = 1 To lLetzteZeile
    For j = 1 To lLetzteSpalte
    arBereichFormel(i, j) = Replace(Replace(arBereichFormel(i, j), "'", ""), "!", "")
    ' prüfen ob es eine Formel ist (spart Zeit wenn nicht)
    If InStr(arBereichFormel(i, j), "=") > 0 Then
    ' schauen ob der Suchbegriff vorkommt - dazu prüft er direkt jeden Suchbegriff
    For k = 1 To UBound(arSuche) ' ubound = Nr. vom letzten Eintrag
    If InStr(arBereichFormel(i, j), arSuche(k)) > 0 Then
    ' wurde der Begriff gefunden, füllen wir das Array
    ' würde man das Ergebnis direkt eintragen würde es auch wieder ewig  _
    dauern
    m = 1
    Do
    ' erstes / nächstes Vorkommen von der Suche finden
    ' m bekommt den Wert von der gefundenen Stelle + Länge vom Suchwort
    ' m und n haben jetzt die Stelle wo der Zellverweis anfängt
    m = InStr(m, arBereichFormel(i, j), arSuche(k)) + Len(arSuche(k))
    ' brauchen wir weiter unten für den "Startpunkt"
    n = m
    Do
    m = m + 1
    If m > Len(arBereichFormel(i, j)) Then Exit Do
    'solang m um 1 erhöhen bis die aktuelle Stelle kein Buchstabe  _
    ist
    'das machen wir auch um das $ Zeichen für absolute Adressen  _
    einzubeziehen
    Loop While (IsNumeric(Mid(arBereichFormel(i, j), m, 1)) = False Or  _
    Mid(arBereichFormel(i, j), m, 1) = False)
    Do
    'um paar Fehler zu umschiffen prüfen wir ob m kleiner der Länge  _
    von der Formel ist
    If m < Len(arBereichFormel(i, j)) Then m = m + 1
    'wenn die aktuelle Position eine Zahl ist nichts tun
    If Mid(arBereichFormel(i, j), m, 1) Like "#" Then
    Else
    'ist es keine Zahl dann m-1 und do loop verlassen (wollen  _
    ja nicht zu viel _
    haben)
    m = m - 1
    Exit Do
    End If
    'durchlaufen solang es eine Zahl ist und wir noch nicht am Ende  _
    der Formel sind
    Loop While IsNumeric(Mid(arBereichFormel(i, j), m, 1)) = True And m  _
    <> Len( _
    arBereichFormel(i, j))
    'Ergebnisse eintragen
    'da wir bei A1 anfangen, können wir aus i und j die aktuelle Zelle  _
    in A1 Schreibweise _
    ermitteln
    'On Error GoTo Fehler
    arErgebnis(z, 1) = Replace(Cells(i, j).Address, "$", "")
    arErgebnis(z, 2) = Worksheets(a).Name
    arErgebnis(z, 3) = arBereichWert(i, j)
    'auf wen verwiesen wird nehmen wir von der Suche
    'da steht zum Beispiel 'Blatt'!
    'wir wolle es ab dem 2. Zeichen + Zeichenlänge = Anzahl Zeichen -  _
    2x ' und 1x ! also 3
    arErgebnis(z, 5) = Mid(arSuche(k), 1, Len(arSuche(k)))
    'Die Zelle auf die verwiesen wird ist der Startpunkt n
    länge = m - n + 1
    arErgebnis(z, 6) = Mid(arBereichFormel(i, j), n, m - n + 1)
    'Fehler:
    z = z + 1
    m = m - 1
    'solang wiederholen wie er das Suchwort nach dem aktuellen findet
    Loop While InStr(m, arBereichFormel(i, j), arSuche(k)) > 0
    End If
    Next
    End If
    Next
    Next
    ' er hats das Blatt durchgeackert und wenn mindestens 1 Ergebnis vorliegt, trägt er es ein
    If z <> 1 Then
    ' nächste freie Zeile suchen
    lLetzteZeile = Sheets("SheetSearchList").Cells(Rows.Count, 3).End(xlUp).Row + 1
    ' das gesamte Array ins Blatt eintragen
    Worksheets("SheetSearchList").Cells(lLetzteZeile, 3).Resize(z - 1, 6).Value =  _
    arErgebnis
    End If
    ' wiederholen bis alle Blätter durch sind
    Next
    ' arrays löschen
    Erase arBereichFormel
    Erase arBereichWert
    Erase arErgebnis
    ' 1. Blatt aktivieren
    Sheets("SheetMatrixOverview").Activate
    Cells(1, 1).Value = "Matrix:"
    For i = 3 To Worksheets.Count
    Cells(i - 1, 1).Value = Worksheets(i).Name
    Cells(1, i - 1).Value = Worksheets(i).Name
    Next
    ' wir berechnen das direkt in VBA ohne Umweg
    lLetzteZeile = Sheets("SheetSearchList").Cells(Rows.Count, 3).End(xlUp).Row
    For i = 3 To Worksheets.Count
    For j = 3 To Worksheets.Count
    Cells(i - 1, j - 1).Value = Application.WorksheetFunction.CountIfs(Sheets(" _
    SheetSearchList").range("D2:D" & lLetzteZeile), Worksheets(i).Name, Sheets("SheetSearchList").range("G2:G" & lLetzteZeile), Worksheets(j).Name)
    Next
    Next
    ' alles wieder einschalten
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Exit Sub
    Error:
    Erase arBereichFormel
    Erase arBereichWert
    Erase arErgebnis
    Application.Calculation = xlCalculationAutomatic ' automat.Berechnung einschalten falls ein  _
    Fehler ausgegeben wird
    MsgBox ("Error 404 - Page not Found")
    End Sub
    

    Beliebteste Forumthreads (12 Monate)

    Anzeige

    Beliebteste Forumthreads (12 Monate)

    Anzeige
    Anzeige
    Anzeige