Verfasst am: 04.03.2020, 14:22
Titel: actxserver ColorIndex in Schleife bestimmen
Moin liebes Forum,
ich möchte über Matlab zwei Excel-Tabellen miteinander vergleichen und nach dem Vergleich eine neue Tabelle erstellen, die die Unterschiede zeigt. Ich muss sagen, dass es ziemlich gut läuft und ich schöne Fortschritte mache.
Die Zellen in der Spalte 'M' können vier verschiedene Wörter enthalten, wobei jedem Wort eine bestimmte Füllfarbe zugeordnet wird. Nun möchte ich abfragen welche Werte sich in den Zellen der Spalte 'M' befinden und welche Füllfarben vorliegen.
% Einlesen der Excel-Tabelle [S.num_1,S.txt_1,S.raw_1] = xlsread(file);
S.DF_table_1 = readtable(file);
% Verbindung zu Excel erstellen
S.excel_1 = actxserver('Excel.Application');
% optional, make excel visible
excel.Visible = true;
% open excel file
S.workbook_1 = S.excel_1.Workbooks.Open(file);
% get worksheet reference
S.worksheet_1 = S.workbook_1.Worksheets.Item(1);
% Länge der Excel-Liste bestimmen
S.length_1 = length(S.raw_1);
S.length_1 = sprintf('%d',S.length_1);
S.M_end_1 = (strcat('M6:','M', S.length_1)); % Spalte festlegen und Anzahl der Zeilen hinzufügen --> Range
% Inhalt der Zelle
S.excelRange_1 = get(S.worksheet_1,'Range', S.M_end_1); % An dieser Stelle habe ich bspw. eine Range von M6:M5306 --> FUNKTIONIERT BESTENS
S.Cell_Inhalt_M_1 = S.excelRange_1.Value; % dementsprechend habe ich an dieser Stelle ein 5306x1 cell
Nun möchte ich quasi das gleiche für den ColorIndex machen. Wenn ich den folgenden Code verwende, wird in meinem Fall eine 43 ausgegeben, was der Farbe grün entspricht und auch so in der Excel-Tabelle vorliegt.
Wenn in meiner Excel bspw. die Zellen 'M6:M9' grün (ColorIndex = 43) sind und ich diese Range im Code eingebe, wird mir nur eine 1x1 int32 mit dem Wert 43 im Workspace hinterlegt. Allerdings hätte ich gerne ein 4x1 cell, die in jeder Zelle eine 43 enthält.
Code:
S.ColorIndex_1 = S.worksheet_1.Range('M6:M9').Interior.ColorIndex; % es wird zwar kein Fehler ausgegeben allerdings habe ich hier kein 4x1 cell wie ich ihn bei der gleichen Range beim Bestimmen des Value hätte
Noch blöder wird es, wenn dann Zelle 'M10' bspw. gelb (ColorIndex = 6) ist. Wenn ich den oberen Code mit einer Range von 'M6:M10' eingebe, wird mir ein 1x1 double mit 'NaN' ausgespuckt. Ich kann mir leider nicht erklären warum das so ist.
Dementsprechend wären die Fragen wie folgt:
1.) Warum kann ich bei der Bestimmung des ColorIndex keine Range eingeben, wie ich es bei der Bestimmung des Value mache. Bzw. warum wird kein cell ausgegeben, dass für jede Excel-Zelle einen Wert beinhaltet.
2.) Warum wird ein 'NaN' ausgegeben, wenn die Zellen innerhalb der Range verschiedene Füllfarben beinhalten.
Ich hoffe, dass das nicht zu kompliziert klingt und ich genügend Informationen erwähnt habe. Ich glaube auch, dass es nicht einfach sein wird eine Antwort darauf zu finden, da das erstellen von Excel Tabellen mit actxserver nicht sehr gängig ist.
meine Vermutung wäre, dass Excel das in der Form einfach nicht unterstützt.
Am einfachsten ist es wohl, wenn du in einer Schleife für jede Zelle einzeln den Farbwert abfragst und das in MATLAB zu einem Array zusammensetzt.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Dass Excel das nicht unterstützt, hatte ich auch schon vermutet aber ein wenig Hoffnung hatte ich trotzdem , dass das vllt jemand widerlegen kann.
Ich muss sagen, dass ich mit Matlab einigermaßen klarkomme und mir immer wieder nette Dinge gelingen aber ich habe immer wieder Probleme mit Schleifen.
Für den vorliegenden Fall kriege ich die Schleife nicht hin. Wahrscheinlich ist das ganz easy nur bin ich zu blöd dafür.
Ich hätte versucht das irgendwie so zu lösen:
Code:
for i = 6:M_end
ii = i + 1;
ii = num2str(ii);
m = strcat('M',ii);
ColorIndex = S.worksheet_1.Range(m).Interior.ColorIndex;
end
all_i = 6:M_end;
ColorIndex = zeros(size(all_i));
for k = 1:numel(all_i)
i = all_i(k);
m = strcat('M',num2str(i));
ColorIndex(k) = S.worksheet_1.Range(m).Interior.ColorIndex;
end
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Es kann trotzdem vorkommen, dass eine ID aus Tabelle 2 und die dazugehörige Zeile gelöscht wurden, weil der Inhalt nicht mehr benötigt wird. Ich muss nun prüfen, ob alle IDs aus ID_1 auch in ID_2 vorhanden sind.
Mein erster Gedanke war einfach
Code:
ID_1 = S.raw_1(6:end,12); % Spalte L mit den ID's aus Tabelle 1
ID_2 = S.raw_2(6:end,12); % Spalte L mit den ID's aus Tabelle 2
S.comp_ID = strcmp(S.ID_1(:,1), S.ID_2(:,1)); % Vergleich der einzelnen Zellen
S.comp_ID = double(S.comp_ID);
S.row_zeros_ID = find(S.comp_ID == 0); % findet die Nullen im Vergleich. Null bedeutet, dass IDs an der Stelle S.row_zeros nicht übereinstimmen
Naja...nun ist mir aufgefallen, dass der Vergleich nicht mehr möglich ist, wenn in Tabelle 2 eine Zeile mit der dazugehörigen ID gelöscht wird. Dann verschieben sich bei Tabelle 2 alle Zeilen (die unter der gelöschten Zeile waren) um einen Wert nach oben, sodass sich die gleichen ID's nicht mehr in den gleichen Zeilen befinden.
Deswegen habe ich mir gedacht, dass jede ID einzeln in einer schleife gesucht werden muss. Ich habe versucht eine Lösung zu finden, indem ich mich an der oben geposteten Schleife orientiert habe.
Code:
ID_1 = S.raw_1(6:end,12); % alle ID's aus Tabelle 1
ID_2 = S.raw_2(6:end,12); % alle ID's aus Tabelle 2
N = length(S.raw_1);
all_i = 6:N;
find_ID = zeros(size(all_i));
Ich lade mal zwei Tabellen und einen an die beiden Tabellen angepasste m-File hoch. Vielleicht hat ja jemand eine Idee. Ich vermute, dass es wieder nur eine Kleinigkeit ist. Aber um Schleifen einzusetzen, bin ich einfach zu doof.
VG
Krys
P.S.
Also nochmal vereinfacht gesagt...ich müsste prüfen, ob ID_2{1,12} in ID_1 vorhanden ist. Im nächsten Schritt : Ist ID_2{2,12} in ID_1 enthalten
Ist ID_2{3,12} in ID_1 enthalten usw.
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
ich muss leider nochmal nerven, weil ich seit Tagen nicht weiterkomme und ich mir auch nicht sicher bin, ob mein Vorhaben überhaupt umsetzbar ist.
Ich hatte ja schon ein wenig erläutert was ich vorhabe.
Ich versuche es nochmal kurz zusammenzufassen.
Ich möchte zwei Tabellen miteinander vergleichen, die zum größten Teil identisch sind. Es kann vorkommen, dass in der zweiten Tabelle komplette Zeilen fehlen oder Inhalte in den Zellen geändert wurden. Um es zu verdeutlichen lade ich zwei Tabellen hoch, die so aufgebaut sind wie die Tabellen, die ich vor ein paar Tagen hochgeladen habe. Allerdings sind diese einfacher aufgebaut, sodass man das Problem vielleicht schneller versteht.
In den beiden Tabellen befinden sich in Spalte B sogenannte IDs. Im ersten Schritt soll ich prüfen, ob welche davon fehlen bzw. die ganze dazugehörige Zeile. Ist dies der Fall, wird ein neues Blatt erstellt und die Zeile dieser ID kopiert und in das neue Blatt eingesetzt. Generell bekomme ich das hin.
ID_row_zeros_str = string(num2str(ID_row_zeros)); % ID_row_zeros_str gibt an welche Zeilen fehlen. In dem Fall ist es Zeile 8, 22, 30, 31. Diese vier Zeilen sind in der 1.Tabelle lila markiert, damit man sie schneller findet.
% ########## copy the first 5 rows ############
% im Folgenden wird die Tabellenkopfzeile vom ersten Blatt in das zweite Blatt kopiert
% ########## paste deleted rows to the 2nd sheet ##############
% Im folgenden Teil befindet sich mein Problem. Ich kann die vier fehlenden Zeilen in das zweite Blatt kopieren. Allerdings mache ich das einzeln. Wenn aber ID_row_zeros 200 fehlende Zeilen enthält, würde ich mir wünschen, dass diese einfach komplett in das zweite Blatt eingefügt werden und nicht wie im folgenden Code einzeln.
% rein theoretisch sage ich, dass alle ID_row_zeros Werte in das zweite Blatt eingefügt werden sollen aber so geht das leider nicht. Da wäre es super, wenn es eine passende Syntax geben würde.
ich musste jetzt lange suchen um zu finden, was eigentlich die Frage ist...
Die letzte der 4 Zeilen sollte wohl so lauten:
handles.worksheet_1.Rows.Item(ID_row_zeros(4,1)).Copy;
handles.workbook_1.Worksheets.Item(2).Range('A9').PasteSpecial(13);
Dann kann man das in einer for-Schleife machen:
Code:
for k = 1:irgendwas
handles.worksheet_1.Rows.Item(ID_row_zeros(k,1)).Copy;
handles.workbook_1.Worksheets.Item(2).Range(['A', num2str(k+5)]).PasteSpecial(13);
end
Ob es auch ohne geht, ist eine Frage dessen, was Excel unterstützt.
Generell wäre mein Vorschlag zu versuchen, die Daten nach MATLAB zu importieren, so viel wie möglich dort zu machen, und das dann wieder nach Excel zu exportieren. Diese VBA-Befehle machen ja nicht wirklich Spaß, und da hilft es auch nichts, das aus MATLAB heraus zu machen.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Ich habe vorher bei Mathworks um Hilfe gebeten, weil ich nicht immer hier nerven möchte aber da konnte mir leider keiner helfen. Generell wurde mir auch dort empfohlen es so zu machen wie du es gesagt hast.
Also in Matlab importieren und, dort bearbeiten und anschließend wieder als excel abspeichern. Aber gerade bin ich so weit und mir fällt es gerade schwer den Aufwand abzuschätzen das alles wieder "rückgängig" zu machen, was ich bisher aufgebaut habe.
Nochmals Danke. Vielleicht werde ich deinen Rat befolgen, wenn ich auf das nächste Problem stoße.
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.