VBA Array Slices (nicht im pythonischen Sinn)

8

Wie soll ich diese Funktion implementieren?

%Vor%

Angenommen, ich wollte eine Scheibe eines Arrays. Ich spezifiziere ein Array, eine Dimension und einen Index für diese Dimension, für die ich das Slice haben möchte.

Als ein konkretes Beispiel nehme ich an, dass ich das folgende 5x4 2D-Array habe

%Vor%

Wenn die horizontale Dimension 1 und die vertikale 2 ist, wäre der Rückgabewert von ArraySlice(array, 1, 3) ein 1x4 2D-Array. Die gewählte Dimension 2 wurde abgeflacht und die einzigen verbleibenden Werte sind diejenigen, die ursprünglich den Index 3 auf Dimension 2 hatten:

%Vor%

Wie würden Sie das in VBA implementieren? Die einzigen Implementierungen, an die ich denken kann, wären CopyMemory, wenn ich nicht die Anzahl der zulässigen und fest codierten Dimensionen in jedem Fall beschränke.

HINWEIS: So würde ich die Abmessungen des Arrays ermitteln

AKTUALISIEREN

Hier sind ein paar weitere Beispiele für die Operation

Für das 2D-Array

%Vor%

Das Ergebnis von ArraySlice(array, 2, 2) wäre

%Vor%

Angenommen, ich hätte ein 3x3x3-Array, das aus den folgenden zweidimensionalen Schichten besteht Dieses Beispiel wurde geändert, um es klarer zu machen

%Vor%

(so konstruiert)

%Vor%

(die Dimensionen werden im mathematischen x, y, z Sinne verwendet, im Gegensatz zu den Zeilen / Spalten Sinn)

Das Ergebnis von ArraySlice(array, 3, 1) wäre das 3x3x1 Array

%Vor%

Das Ergebnis von ArraySlice(array, 2, 2) wäre das 3x1x3 Array

%Vor%

UPDATE2

Für DavidZemens ist hier ein Beispiel, das eine einfachere Verfolgung der beteiligten Elemente ermöglicht:

Für ein 3x3x3-Array, das so aufgebaut ist

%Vor%

Das Ergebnis von ArraySlice(array, 3, 1) wäre das 3x3x1 Array

%Vor%

ENDGÜLTIGES UPDATE

Hier ist die vollständige Lösung - Sie können davon ausgehen, dass die Array-Funktionen implementiert sind, wie @GSerg in der akzeptierten Antwort vorschlägt. Ich entschied, dass es sinnvoller ist, die geschnittene Dimension vollständig zu reduzieren. Wenn also eine Scheibe eines 3x3x3-Arrays ("cube") 3x1x3 ist, wird sie auf 3x3 abgeflacht. Ich muss noch den Fall lösen, bei dem das Abflachen eines 1-dimensionalen Arrays mit dieser Methode ein 0-dimensionales Array ergibt.

%Vor%     
Blackhawk 09.09.2015, 19:50
quelle

3 Antworten

5

Ich bin mir nicht sicher, ob ich die Logik und die Verbindung zwischen den Funktionsargumenten und dem Ergebnis vollständig verstehe, aber es gibt bereits eine generische Element-Accessor-Funktion, SafeArrayGetElement . Sie können auf ein Element eines Arrays zugreifen, dessen Dimensionen bei der Kompilierung unbekannt sind. Sie benötigen lediglich den Array-Pointer (nur als Referenz; Code in dieser Antwort wurde verbessert) .

In einem separaten Modul:

%Vor%

Verwendung:

%Vor%

Ich glaube, dass Sie mit diesem Basisblock Ihre Logik leicht aufbauen können, obwohl es langsamer sein könnte, als Sie wollen.
Es gibt einige Typprüfungen im Code, die Sie entfernen können - dann wird es schneller, aber Sie müssen sicherstellen, dass Sie nur Arrays mit dem richtigen zugrunde liegenden Typ übergeben. Sie können den pArray auch zwischenspeichern und GetArrayElement anstelle eines rohen Arrays akzeptieren.

    
GSerg 12.09.2015, 14:23
quelle
3

Mein vollständiger Code ist unten, der arr-Eingang ist ein 1, 2 oder 3-dimensionales Array, das 1-dimensionale Array gibt false zurück.

%Vor%


Einfach mit dem folgenden Code testen

%Vor%     
Adisak Anusornsrirung 14.09.2015 13:13
quelle
1

Nun, da ich all das geschrieben habe und festgestellt habe, dass Sie einen ähnlichen Elementsetzer benötigen (basierend auf SafeArrayPutElement anstelle von SafeArrayGetElement ) und ein generisches Array-Erstellungsroutine , ich denke, ob es wirklich eine schlechte Sache ist, alle 60 Fälle fest zu codieren.

Der Grund ist, dass es in einem VBA-Array höchstens 60 Dimensionen geben kann, und 60 Fälle sind nicht schwer zu codieren

Ich habe diesen Code nicht einmal eingegeben, ich habe einige Excel-Formeln verwendet, um ihn zu generieren:

%Vor%

Leider ist es etwa doppelt so lang wie es in einem Post erlaubt ist, also gibt es einen Link zur Vollversion: Ссылка

    
GSerg 12.09.2015 15:45
quelle

Tags und Links