Forum: Gesperrte Threads Excel: If-Else Alternativen


von siebert (Gast)


Lesenswert?

Hallo, ich habe mal wieder ein Problem in Excel:

Ich habe ein ca 1000x1000 großes Feld mit IF-ELSE Bedingung in jeder 
Zelle.
Das Problem ist, dass die Dateigröße dadurch schnell durch die Decke 
schießt und das Programm langsam wird.

Daher möchte ich euch Fragen, ob ihr eine Alternative habt?
Würde es Abhilfe schaffen, wenn ich die Abfrage in VBA schreibe?

Es geht konkret im Folgendes:

in jeder Zelle des 1000x1000 Feldes befindet sich ein Wert.
Wenn dieser Wert > X , dann schreibe eine 1 in die Zelle,
wenn Zellwert < X, dann lasse die Zelle leer.
Und das muss für jede Zelle gemacht werden.

Beste Grüße,
Siebert

: Verschoben durch Moderator
von Jim M. (turboj)


Lesenswert?

siebert schrieb:
> Würde es Abhilfe schaffen, wenn ich die Abfrage in VBA schreibe?

Kannst Du denn VBA?

Wenn ja, würde das Schreiben einer so "einfachen" Funktion weniger lange 
dauern als so einen Beitrag hier posten. Dann würde man relativ schnell 
merken ob das schneller läuft - die Chance besteht durchaus.

Wir können Dir das jedenfalls nicht ohne Zugriff auf die Originaldaten 
beantworten.

von Fäzes, der Heilige Stuhl (Gast)


Lesenswert?

Wenn du so programmierst, wie du beschreibst, lass das Programmieren 
lieber sein.

siebert schrieb:
> in jeder Zelle des 1000x1000 Feldes befindet sich ein Wert.
> Wenn dieser Wert > X , dann schreibe eine 1 in die Zelle,
> wenn Zellwert < X, dann lasse die Zelle leer.

Wenn schon ein Wert in der Zelle steht, wie soll dann noch "eine 1" in 
die Zelle geschrieben werden können? Eine Zelle kann nur einen Wert 
enthalten.

von siebert (Gast)


Lesenswert?

Natürlich in eine weiter nach unten verschobene tabelle.
Nämlich so:

nehmen wir an ich habe in A1:B2 werte stehen, die mit x verglichen
werden sollen

dann schreibe ich in A5:B6

Wenn(A1>X;1;"")
also A1 > X, dann schreibe eine 1 in A5, sonst lasse A5 leer
das selbe dann für B5, A6 und B6.

und das eben in einer "Tabelle" mit 1000 Zeilen und Spalten.

Fäzes, der Heilige Stuhl schrieb:
> Wenn du so programmierst, wie du beschreibst, lass das Programmieren
> lieber sein.

Das hat nichts mit Programmierkünsten zu tun, ich bin nur eben kein 
Excel Profi. Daher Frage ich ja hier nach alternativen. Wie ich das z.B. 
in VBA einfach schreibe ist nicht die Frage, sondern ob es eine 
effizientere Funktion gibt.

von Fäzes, der Heilige Stuhl (Gast)


Lesenswert?

Wenn man dir helfen will, muss man verstehen, was du willst. OK, jetzt 
ist es verständlich. Mein Excel ist auch in die Knie gegangen ;) VBA ist 
der Ausweg.

von Fäzes, der Heilige Stuhl (Gast)


Lesenswert?

1
Sub Analyselauf()
2
  Dim rngErgebnisTabelle As Range
3
  Dim rngLeseTabelle As Range
4
  Dim iCalcMerker As Long
5
  Dim iColumn As Long
6
  Dim iRow As Long
7
  
8
  'Das muss von Hand angepasst werden
9
  Const cBereich_LeseTabelle = "A1:B2"
10
  Const cBereich_ErgebnisTabelle = "A5:B6"
11
  Const cVergleichswert = 5
12
13
  'Das Script bezieht sich auf das aktuell geöffnete Sheet
14
  With ActiveSheet
15
  
16
    'Autoberechnung aus
17
    iCalcMerker = Application.Calculation
18
    Application.Calculation = xlCalculationManual
19
    
20
    'Initialisieren
21
    Set rngLeseTabelle = .Range(cBereich_LeseTabelle)
22
    Set rngErgebnisTabelle = .Range(cBereich_ErgebnisTabelle)
23
    
24
    'Müllfilter
25
    If (rngLeseTabelle.Columns.Count <> rngErgebnisTabelle.Columns.Count) _
26
    Or (rngLeseTabelle.Rows.Count <> rngErgebnisTabelle.Rows.Count) Then
27
       MsgBox "Beide Tabellen müssen gleich groß sein", vbCritical
28
       Stop
29
    End If
30
    
31
    'ErgebnisTabelle löschen
32
    rngErgebnisTabelle.Cells = ""
33
    
34
    'ErgebnisTabelle neu bestücken
35
    For iRow = 1 To rngLeseTabelle.Rows.Count
36
      
37
      'Nur fürs Auge: Zeilenwechsel anzeigen
38
      rngErgebnisTabelle.Cells(iRow, 1).Select
39
      DoEvents
40
      
41
      'Zelle in Lesetabelle analysieren und Ergebnis in ErgebnisTabelle schreiben
42
      For iColumn = 1 To rngLeseTabelle.Columns.Count
43
        If rngLeseTabelle.Cells(iRow, iColumn) > cVergleichswert Then
44
           rngErgebnisTabelle.Cells(iRow, iColumn) = 1
45
        Else
46
           rngErgebnisTabelle.Cells(iRow, iColumn) = ""
47
        End If
48
      Next iColumn
49
    Next iRow
50
  End With
51
52
  'Autoberechnung wiederherstellen
53
  Application.Calculation = iCalcMerker
54
End Sub

von Yalu X. (yalu) (Moderator)


Lesenswert?

siebert schrieb:
> Das Problem ist, dass die Dateigröße dadurch schnell durch die Decke
> schießt und das Programm langsam wird.
>
> Daher möchte ich euch Fragen, ob ihr eine Alternative habt?

Da Excel nicht gut zur Bearbeitung größerer Datenmengen geeignet ist,
würde ich als Alternative Python/Numpy, Octave, Scilab, R, Matlab oder
irgendetwas in dieser Richtung vorschlagen.

Mit Numpy sähe das in etwa wie folgt aus:

Die Matrix daten0 enthalte die 1000 × 1000 Zahlenwerte, bspw. 
generiert mit

1
daten0 = np.random.rand(1000, 1000)

1
[[0.6789575  0.54717829 0.94515349 ... 0.90404275 0.54632823 0.361212  ]
2
 [0.75947052 0.64638551 0.27401276 ... 0.66026767 0.48927502 0.50237513]
3
 [0.2509503  0.92464859 0.8825331  ... 0.92142745 0.50211536 0.21358945]
4
 ...
5
 [0.22735865 0.32949274 0.88273482 ... 0.23290303 0.33973415 0.14164492]
6
 [0.88863819 0.82135558 0.48438359 ... 0.61349826 0.23663658 0.30137669]
7
 [0.42845457 0.1880116  0.39903286 ... 0.59569642 0.58733752 0.90263999]]


Den Vergleichswert legst du bspw. mit

1
x = 0.3

fest.

Mit

1
daten1 = daten0 > x

erstellst du daraus eine zweite 1000×1000-Matrix, deren Elemente True
(für alle Elemente > x) oder False (für alle anderen) sind:

1
[[ True  True  True ...  True  True  True]
2
 [ True  True False ...  True  True  True]
3
 [False  True  True ...  True  True False]
4
 ...
5
 [False  True  True ... False  True False]
6
 [ True  True  True ...  True False  True]
7
 [ True False  True ...  True  True  True]]

Falls die Ergebnisse nicht True und False, sondern 1 und "nichts" sein
sollen, geht das so:

1
daten2 = np.where(daten0 > x, 1, None)

1
[[   1    1    1 ...    1    1    1]
2
 [   1    1 None ...    1    1    1]
3
 [None    1    1 ...    1    1 None]
4
 ...
5
 [None    1    1 ... None    1 None]
6
 [   1    1    1 ...    1 None    1]
7
 [   1 None    1 ...    1    1    1]]

("None" ist das "Nichts" in Python)

Die Anweisung

1
daten1 = daten0 > x

bzw.

1
daten2 = np.where(daten0 > x, 1, None)

wird dabei schneller ausgeführt als du gucken kannst :)

von Peter M. (r2d3)


Lesenswert?

siebert schrieb:
> Hallo, ich habe mal wieder ein Problem in Excel:
>
> Ich habe ein ca 1000x1000 großes Feld mit IF-ELSE Bedingung in jeder
> Zelle.

Welchen Sinn hat es, Deine Frage zweimal zu stellen?

Beitrag "Excel langsam trotz gutem PC"

Wenn Du sie jetzt noch mal stellst, hast Du bestimmt insgesamt dreimal 
so viele Antworten - nur keine Antwort, die auf Deine Frage möglichst 
genau eingeht.

Und wer später mal ähnliche Symptome hat und auf µc.net nach Lösungen 
sucht, freut sich bestimmt.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.