Daten sortieren

Hallo Experten,

ich stehe hier vor einem Problem, bei dem ich ohne Hilfe nicht weiterkomme:

Ich habe automatisch erzeugte Inventurdaten, die ich bereits in eine Excel-Tabelle übernommen habe. Jede Zeile beginnt mit der Inventarnummer des PCs, dann folgt die Betriebssystemversion und dann (unsortiert) die auf diesem PC installierten Anwendungen.

In dieser Form kann ich aber mit den Daten nicht viel anfangen. Es sollen daraus später mal z.B. Statistiken gezogen werden („auf wieviel PC’s läuft noch Office95?“). Dazu müsste aber z.B. der Eintrag „Office95“ bei allen Zeilen an der selben Position stehen. Tut er aber natürlich nicht.

Mein Traum wäre eigentlich eine Tabelle, in der ganz links die Inv.Nummer steht, als Spaltenüberschriften alle Betriebssysteme und Anwendungen und in den Feldern nur noch boolsche Werte…

Ihr merkt, ich bin relativ plan- und ratlos! Ich habe hier auch MS-Access, wenn es damit besser ginge. Damit kenne ich mich aber noch viel weniger aus als mit Excel!

Hat jemand ein paar Tipps für mich? Ansonsten wird das wohl in VIEL Handarbeit ausarten…

Gruß und Danke im Voraus.
Stefan

hallöchen!

aus deinen schilderungen kann ich leider nicht die struktur deiner tabelle erkennen.
man sollte dein problem aber mit den text-funktionen in den griff bekommen.

wenn du mit diesen funktionen nicht zurecht kommst, schicke mir doch ein kleines muster deiner tabelle. ich versuch es dann mal.

nussi

Hi,

also, was ich habe ist ungefähr dies:

1|win95|A|B|C|D|F|S|U|X
2|win98|B|E|F|T|X| | |
3|winnt|A|C|S| | | | |
4|win95|E|X|Z|Y| | | |
5|winnt|A|E|D|X|Z| | |

wobei die Großbuchstaben jeweils für Anwendungsnamen (im Volltext) stehen. Statt „A“ steht da also „MS Access 97“ oder so.

Was ich haben will ist

1|win95|A|B|C|D| |F|S| |U|X| |
2|win98| |B| | |E|F| |T| |X| |
3|winnt|A| |C| | | |S| | | | |
4|win95| | | | |E| | | | |X|Y|Z
5|winnt|A| | |D|E| | | | |X| |Z

bzw.

 |win95|win98|winnt|A|B|C|D|E|F|S|T|U|X|Y|Z
1| x | | |x|x|x|x| |x|x| |x|x| |
2| | x | | |x| | |x|x| |x| |x| |
3| | | x |x| |x| | | |x| | | | |
4| x | | | | | | |x| | | | |x|x|x
5| | | x |x| | |x|x| | | | |x| |x

(Uff, wat’ ne Tipperei.)

Ich hoffe, es ist verständlich, sonst kann ich Dir morgen aus dem Büro wirklich mal die Datei mailen.

Gruß
Stefan

hi!!!

probiere es mal hiermit:

=WENN(ZÄHLENWENN(A1:E1;„a“);„a“;"")

gib mir bitte eine info, wenn´s dir geholfen hat.

nussi

Jede Zeile beginnt mit

der Inventarnummer des PCs, dann folgt die
Betriebssystemversion und dann (unsortiert) die auf diesem PC
installierten Anwendungen.

In dieser Form kann ich aber mit den Daten nicht viel
anfangen. Es sollen daraus später mal z.B. Statistiken gezogen
werden („auf wieviel PC’s läuft noch Office95?“). Dazu müsste
aber z.B. der Eintrag „Office95“ bei allen Zeilen an der
selben Position stehen. Tut er aber natürlich nicht.

Mein Traum wäre eigentlich eine Tabelle, in der ganz links die
Inv.Nummer steht, als Spaltenüberschriften alle
Betriebssysteme und Anwendungen und in den Feldern nur noch
boolsche Werte…

Das ist ziemlich einfach - unter gewissen Voraussetzungen:

Wenn einer schreibt „MS Access“, ein anderer „access“ und ein letzter „MS Ekzess“ hast du ein Problem. Immer gleiche Schreibung vorausgesetzt bastelst du dir einfach deine Traumtabelle. Die Booleschen Werte erzeugst du z. B. über die Finden-Funktion. Also in der Spalte Word:

=wenn(finden(word;b2)>0;wahr;falsch) - oder vermutlich besser:
=wenn(finden(word;b2)>0;1;0)

Mit Textfunktionen habe ich noch wenig Erfahrung. Wenn es so nicht sofort klappt, sollte doch zumindest die Vorgehensweise deutlich geworden sein.

Schöne Grüße
Siegfried

Hallo Siegfried,

Wenn einer schreibt „MS Access“, ein anderer „access“ und ein
letzter „MS Ekzess“ hast du ein Problem.

Das ist nicht das Problem, da die Daten aus einem Registry-Export kommen.

Immer gleiche
Schreibung vorausgesetzt bastelst du dir einfach deine
Traumtabelle. Die Booleschen Werte erzeugst du z. B. über die
Finden-Funktion. Also in der Spalte Word:

DAS! ist das Problem! Wie ich unten mal in meiner Antwort an nussi verdeutlicht habe, gibt es schlicht keine Spalte „word“, sondern die entsprechenden Einträge sind über beliebige Spalten verstreut.

Aber für die Wahrheitswerte könnte das gehen, wenn ich auch den FINDEN-Befehl garnicht mir diesen Parametern kenne.

Langsam komme ich aber zu der Erkenntnis, dass ich hier wohl mal wieder zu früh auf Excel gegangen bin. Ich bearbeite die Daten sowieso mit einem selbstgestrickten Turbo-Pascal-Programm (uralt aber immer noch brauchbar!). Ich denke, ich werde dies erweitern und die Daten schon vor dem Übergang nach Excel sortieren lassen. Dachte halt, Excel hätte mal wieder irgendwelche Zauber-Funktionen, die kaum einer kennt…

Gruß
Stefan

Hi,

=WENN(ZÄHLENWENN(A1:E1;„a“);„a“;"")

Damit könnte ich zumindest mal sozusagen „händisch“ Statistiken erzeugen.

Ich habe aber Siegfried oben schon geantwortet, dass ich wohl die Daten vor dem Übergang nach Excel aufbereiten lassen werden. Das wird mir alles zu kompliziert!

Gruß und Danke
Stefan

doch doch
Hallo!

Du hast meine Antwort nicht richtig verstanden!

Du bastelst dir einfach deine Tabelle, wie du sie schließlich möchtest. (Also mit den Spalten Word etc.). Nun kannst du in diese Spalten aus der „großen“ Spalte B (in der alle Werte drinstehen) mit Hilfe der Textfunktionen und der Funktionen die ich im vorherigen Beitrag angegeben habe, genau das Gewünschte erreichen. Denke ich.

Schöne Grüße
Siegfried

Wenn noch was unklar ist - heute abend habe ich etwas mehr Zeit!

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Ich habe automatisch erzeugte Inventurdaten, die ich bereits
in eine Excel-Tabelle übernommen habe. Jede Zeile beginnt mit
der Inventarnummer des PCs, dann folgt die
Betriebssystemversion und dann (unsortiert) die auf diesem PC
installierten Anwendungen.

In dieser Form kann ich aber mit den Daten nicht viel
anfangen. Es sollen daraus später mal z.B. Statistiken gezogen
werden („auf wieviel PC’s läuft noch Office95?“). Dazu müsste
aber z.B. der Eintrag „Office95“ bei allen Zeilen an der
selben Position stehen. Tut er aber natürlich nicht.

Mein Traum wäre eigentlich eine Tabelle, in der ganz links die
Inv.Nummer steht, als Spaltenüberschriften alle
Betriebssysteme und Anwendungen und in den Feldern nur noch
boolsche Werte…

Servus Stefan

Mit ein paar Programmier-, Excel-, VBA- und Makro-Kenntnissen ist diese Aufgabe durchaus auch in Excel zu lösen.

Ich habe folgendes Makro gestrickt (und getestet), das die von die gewünschte Aufgabe erledigen sollte:

Sub SoftwareSort()

Dim Spalte As Integer, i1 As Integer, i2 As Integer, i3 As Integer, tzp As Integer, tzs As Integer, swlen As Integer
Dim software As String, sw As String
Dim sw\_neu As Boolean
Dim alles
Const tab1 = "Tabelle1" ' Name der 1. Tabelle (die alle Daten unsortiert enthält)
Const tab2 = "Tabelle2" ' Name der 2. Tabelle (in die die sortieren Daten geschrieben werden sollen)
Const tz = ", " ' Trennzeichen zwischen den Softwareeinträgen

' Inhalt der 2. Tabelle löschen
 Sheets(tab2).Select
 Cells.Select
 Cells.EntireColumn.Delete
' Überschrift kopieren
 Sheets(tab1).Select
 Range("A1:B1").Select
 Selection.Copy
 Sheets(tab2).Select
 Range("A1").Select
 ActiveSheet.Paste
 Application.CutCopyMode = False
 Sheets(tab1).Select
 Spalte = 3
' Bereich ermitteln
 alles = ActiveSheet.UsedRange
' ganzen Bereich (exkl. Überschrift) abarbeiten
 For i1 = 2 To UBound(alles, 1)
 ' Inventarnummer und Betriebssystem kopieren
 Sheets(tab1).Select
 Range(Cells(i1, 1), Cells(i1, 2)).Select
 software = Cells(i1, 3)
 Selection.Copy
 Sheets(tab2).Select
 Cells(i1, 1).Select
 ActiveSheet.Paste
 Application.CutCopyMode = False
 ' Software-String auflösen
 tzp = 1
 tzs = 1
 swlen = Len(software)
 ' Trennzeichen in Software-String suchen
 Do While tzp \> 0 And tzs 0 Then ' Trennzeichen gefunden
 sw = Mid(software, tzs, tzp - tzs) ' einzelne Software extrahieren
 GoSub swteil
 tzs = tzp + Len(tz) ' nächste Teilstringanfangssuchposition
 End If
 Loop
 ' Softwareteilstring nach dem letzten Trennzeichen behandeln
 If tzs neue Spalte
 Cells(1, Spalte) = sw
 Cells(i1, Spalte) = "X"
 Spalte = Spalte + 1
 End If
 Return

End Sub

Die Tabelle mit dem von dir beschriebenen Aufbau wird gelesen und in eine neue Tabelle geschrieben, wobei die 1. beiden Spalten (Inventarnummer und Betriebssystem) 1:1 übernommen werden und dann pro Software-Eintrag eine Spalte erstellt wird mit einem „X“ in der entsprechenden Zeile.
Außerdem wird davon ausgegangen, dass eine Überschriftszeile vorhanden ist, deren erste beide Spalten ebenfalls 1:1 übernommen werden.

Die Namen der alten und der neuen Tabelle sowie das (oder die) Zeichen, durch die die einzelnen Software-Einträge getrennt sind, können im Makro bei den Konstanten definiert werden.

ACHTUNG:
Der Inhalt der 2. Tabelle wird am Anfang kommentarlos gelöscht!
Es wird nicht überprüft, ob die angegebenen Tabellennamen wirklich existieren.

Probier es einfach aus und falls du Probleme damit haben solltest, kannst du dich ja per E-Mail bei mir melden oder ins Forum schreiben.

MfG
Roland

Hat sich erledigt
Hi,

habe mein Pascal-Programm fertig und meine Traumtabelle (als CSV) generiert.

Du bastelst dir einfach deine Tabelle, wie du sie schließlich
möchtest. (Also mit den Spalten Word etc.).

Du machst Dir ja kein Bild, wieviele Anwendungen in einem Rechenzentrum zusammenkommen! Ich musste sogar mein Pascal-Programm nochmal umschreiben, weil Excel nicht soviele Werte horizontal nebeneinander bekam. Es sind über 400! (Allerdings wird auch z.B. „Unterstützung für japanische Internetseiten“ als eine Anwendung gezählt)

Wenn ich die händisch in eine Tabelle eintragen hätte müssen, säße ich an Ostern noch dran :wink:

Gruß und Danke
Stefan

Super!!!
Mööönsch!

Vielen Dank. Genau das was ich gesucht habe. Schade nur, dass ich mal wieder meine Füße nicht stillhalten konnte und das Ganze bereits in Pascal programmiert hatte *ärger*.

Allerdings fischt mein Programm auch noch erst die Dateien aus den Textdateien. Ich häng’s hier zum Vergleich mal an (ist allerdings sehr quick und sehr dirty).

Deine Lösung ist aber auf jeden Fall eleganter!

Gruß
Stefan

program applgrep;

uses dos, ms\_dos, strings, numconv;

const
 maxan = 500;
 slen = 40;
type
 geraet = record
 id: string[20];
 bs: array[1..10] of boolean;
 an: array[1..maxan] of boolean;
 end;

var
 inputdateiname : string;
 inputdatei : text;
 outputdateiname : string;
 outputdatei : text;
 inchar : char;
 instr : string;
 dateinamen : nametree\_p;
 geraete : array[1..80] of geraet;
 geraetcounter : byte;
 bsnamen : array[1..10] of string[50];
 bscounter : byte;
 annamen : array[1..maxan] of string[slen];
 ancounter : integer;

procedure clearall;
 var x,y : integer;
 begin
 bscounter :=0;
 ancounter :=0;
 geraetcounter:= 0;
 for x:=1 to 80 do
 begin
 geraete[x].id:='';
 for y:= 1 to 10 do geraete[x].bs[y]:=false;
 for y:= 1 to maxan do geraete[x].an[y]:=false;
 end;
 for x:=1 to 10 do
 bsnamen[x]:='';
 for x:=1 to maxan do
 annamen[x]:='';
 end;


procedure firststep;
 var s : string;
 t : integer;
 begin
 inc(geraetcounter);
 readln (inputdatei,instr);
 geraete[geraetcounter].id:=short(instr);
 while not eof(inputdatei) do
 begin
 readln(inputdatei,instr);
 s := short(instr);
 if pos('Windows',s)=1 then
 begin
 for t:= 1 to bscounter do
 if bsnamen[t]=s then
 begin
 geraete[geraetcounter].bs[t]:=true;
 close (inputdatei);
 reset (inputdatei);
 readln(inputdatei,s);
 exit;
 end;
 inc(bscounter);
 bsnamen[bscounter]:=s;
 geraete[geraetcounter].bs[bscounter]:=true;
 end;
 end;
 close (inputdatei);
 reset (inputdatei);
 readln(inputdatei,s);
 end;

procedure compute;
 var s : string;
 a : string[slen];
 b : integer;
 t : integer;
 begin
 s:= short (instr);
 if s='' then exit;
 if pos ('QuietDisplay',s) \> 0 then exit;
 b := pos ('"DisplayName"=',s);
 if b \> 0 then
 begin
 a:= copy(s,b+15,length(s)-16);
 for t:= 1 to ancounter do
 if annamen[t]=a then
 begin
 geraete[geraetcounter].an[t]:=true;
 write('.');
 exit;
 end;
 inc(ancounter);
 annamen[ancounter]:=a;
 geraete[geraetcounter].an[ancounter]:=true;
 end;
 end;

procedure write\_output;
 var t,g,b,a : integer;
 begin
 assign (outputdatei,'y:\inventur\inventur.csv');
 rewrite (outputdatei);
 write(outputdatei,'Objekt;');
 for g:= 1 to geraetcounter do
 write(outputdatei,geraete[g].id,';');
 writeln(outputdatei);
 for b := 1 to bscounter do
 begin
 write(outputdatei,bsnamen[b],';');
 for g := 1 to geraetcounter do
 if geraete[g].bs[b]
 then write(outputdatei,'x;')
 else write(outputdatei,' ;');
 writeln(outputdatei);
 end;
 for a := 1 to ancounter do
 begin
 write(outputdatei,annamen[a],';');
 for g := 1 to geraetcounter do
 if geraete[g].an[a]
 then write(outputdatei,'x;')
 else write(outputdatei,' ;');
 writeln(outputdatei);
 end;

 close(outputdatei);
 end;

begin
 clearall;
 build\_nametree(dateinamen,'y:\inventur','\*.txt',false);
 while dateinamennil do
 begin
 inputdateiname:='y:\inventur\'+dateinamen^.name;
 dateinamen:=dateinamen^.next;
 assign (inputdatei, inputdateiname);
 reset (inputdatei);

 firststep;

 while not eof(inputdatei) do
 begin
 readln (inputdatei,instr);
 compute;
 end;
 close(inputdatei);
 end;
 write\_output;
 writeln('fertig.');
end.

Vielen Dank. Genau das was ich gesucht habe. Schade nur, dass
ich mal wieder meine Füße nicht stillhalten konnte und das
Ganze bereits in Pascal programmiert hatte *ärger*.

Allerdings fischt mein Programm auch noch erst die Dateien aus
den Textdateien. Ich häng’s hier zum Vergleich mal an (ist
allerdings sehr quick und sehr dirty).

Deine Lösung ist aber auf jeden Fall eleganter!

Servus Stefan

Meine Lösung ist nicht wirklich elegant, sondern auch eher einigermaßen quick und ziemlich dirty - zumal ich mit VBA eigentlich nicht viel zu tun habe.
Bei meinem Makro wird z.B. nicht darauf Rücksicht genommen, was passiert, wenn es mehr als 256 Spalten (mehr geht in Excel ja nicht) werden - in diesem Fall würde es höchstwahrscheinlich grausam abstürzen.

Ich hab mir schon überlegt, dass man in so einem Fall den Output auf mehrere Tabellen aufteilen könnte, aber das würde evtl. Auswertungen verkomplizieren.

Aber sei doch glücklich, wenn dein Programm das tut, was es soll, und trauere nicht evtl. eleganteren Lösunge nach … :wink:

Programmierergruß
Roland