Laden...

Excel-Zellen formatieren (Text,Währung,Zahl...)

Letzter Beitrag vor 17 Jahren 15 Posts 21.271 Views
Excel-Zellen formatieren (Text,Währung,Zahl...)

Hy Leute,

hab mal ne Frage. Mein Programm arbeitet mit Excel zusammen und übergibt bestimmte Daten. Jetzt passiert es aber öfters, dass die Zellen, an die die Daten übergeben werden nicht richtig formatiert sind.

Ich übergebe z.B. "1.10" und in der Zelle steht dann "1.10.2006".

Könnte einer von euch mir vielleicht mal so 2-3 Befehle schicken, mit denen ich die Zellenformatierung ändern kann?

Und ja, ich habe versucht selbst zu suchen, aber ich finde nur Tips für die "optische" formatierung, also Fett und Unterstrichen und so.

Vielen Dank

underscare

Makro-Recorder

Benutze den Makro-Recorder und übersetze die aufgezeichneten Befehle in C#. Das sollte nicht allzu schwer sein.

moin

übergieb den dezimal punkt mal als ',' dann haste dieses lästigen als datum interpretieren nicht mehr

mfg

@ Rainbird: Danke für die schnelle Antwort, aber wo finde ich diesen "Rekorder"^^. Noch nie mit gearbeitet.

@blackcoin: Hhhm, wäre zwar eine Möglichkeit, aber wird dann nich auch ein "," angezeigt? Das wäre ja bei Daten n bisschen doof.

MAKRO RECORDER unter Extras - Makro - aufzeichen

und danach in den Visual Basic editor unter Modul'n' (n für laufenden Zähler)

ich meine mich zu erinner das sobald Excel ein Datum aus deiner eingabe gemacht hat kannst du dieses Datum nicht mehr in ein Zahl umwandeln

ich hätte da zwar noch einen Tip aber sag erst mal wie du die Daten in Excel reinbekommst

OLEDB ODBC Excel Object CSV Datei .

mfg

Jo vielen Dank, des is ja ne super Funktion.

Könntet ihr den Thread aber vielleicht noch so bis heut abend auflassen? Vielleicht ergibt sich ja noch die eine oder andere Frage, bei der ihr mir helfen könnt.

Ansonsten vielen Dank für eure Hilfe 😉

-greetz-

underscare

Normalerweise bleiben die Threads immer auf (Natürlich gibt es ausnahmen, aber nur wenige)

mfg

So, hab aber jetzt ein anderes Problem, und zwar muss ich 2 Reihen an Zellen kopieren.

Und zwar soll das so aussehen:


xxxxxxxxxxxxxxxxxxxx  (<<- Sind die Zellen, die schon existieren)
xxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyy    (<<- Unter den 2 exisitierenden Zeilen, werden 2 neue
yyyyyyyyyyyyyyyyyyyy    eingefügt. In Diesen Zellen sollen die oberen beiden  
                                       kopiert werden

Ich hab schon einen Beitrag in diesem Forum gelesen, aber ihn 1. nicht ganz verstanden, und 2. nachdem ich versucht habe, ihn zu verstehen, hat er nicht geklappt^^.

Also ich bin weißgott nicht derjenige, der sich Code sucht, den kopiert ohne ihn zuu verstehen.

Aber ich häng mittlerwele Stunden an dem Prog und hab Kopfschmerzen 😁 Also so eine kleine Anregung wäre echt geil.

Achso, nebenbei, ich arbeite mit Ranges, also nicht mit der Cell eigenschaft. Wenn ich diese brauch, wär vielleicht so ein begleitener Satz hilfreich 😉

Auf jeden Fall vielen Dank im Vorraus,

-greetz-

underscare

Edit: Ich hab irgendwo was von get_Offset gelesen, hat das was damit zu tun?

Edit2: Auf Excel greif ich über die PIA's von Excel 2003 zu.

Range-Objekt

Versuchs mal mit Range.Cells(x,x) oder z.B. mit Range("B5"). So kannst Du bestimmte Zelle direkt adressieren.

Welchen Artikel hast Du gelesen?

Was hat nicht geklappt?

Puuh, find den Beitrag grade nicht..

Aber mal was anderes, ne Zeile hinzufügen is ja recht einfach, aber wie lösche ich eine bestimmte Zeile?? Hab alles erdenkliche Versucht, saß da glaub ich jetzt ne Stunde dran...

Kennt vielleicht grade einer den Befehl dafür?

PS: Der VBA Recorder konnte mir nicht weiter helfen...

Range-Objekt

Hallo,
durch Googeln wärest Du fündig geworden.

Hier mal ein Beispiel:


	private void ganzeZeileloeschen()
	{
	int  intRow = 3;
	xlrange = (Excel.Range)xlsheet.Rows[intRow, Type.Missing];
	xlrange.Interior.ColorIndex = 9;
	xlrange.EntireRow.Delete(Excel.XlInsertShiftDirection.xlShiftDown);
	}


Gruß
ludwig

Vielen Dank Lugwig...komisch, habs mit google versucht....hab durchs ganze suchen bestimmt den wald vor lauter bäumen nicht mehr gesehen 😉

Grüsse,

Mirco

Und wieder ein Problemchen 😉

Und zwar:

Mein Programm öffnet ja eine Vorlage, verändert sie und speichert sie dann unter neuem Namen.

Wenn ich Excel dann aber schliesse, fragt er mich trotzdem noch, ob ich die Änderungen speichern möchte, obwohl nach dem Speichern per Code gar keine Änderungen mehr vorgenommen habe...

Diese Abfrage ist sehr lästig, kann man die irgendwie abschalten??

Grüsse,

Mirco

//edit: Habs rausgefunden. Geht mit excellapp.DisplayAlerts = false;

Allerdings, wenn ich dann an der geöffneten Datei etwas verändere, fragt der mich nicht, ob ich speichern will.....Ich müsste also DisplayAlerts wieder auf true setzen, nachdem etwas (durch den User manuell) verändert wurde...

Nun der Knackpunkt: Wie frag ich von meinem Programm aus ab, ob an der Excel Datei etwas verändert wurde?

Hi Leute,

genau der Thread den ich suchte 🙂. Allerdings komme ich einfach nicht dahinter, wieso meine Spalten nicht formatiert werden.

Ich erstelle ein Excel file, nach Rainbirds Beispiel [1], danke an dieser Stelle an Rainbird 🙂. Das ganze klappt wunderbar. Nur jetzt sollte ich eben die Spalten noch formatieren. Da ergab sich bei mir die erste Frage, wie selektiere ich eine ganze Spalte?

Irgendwo habe ich dann das im Forum gefunden:


Excel.Range oRange = (Excel.Range)ws.Columns[SpaltenNummer, Type.Missing];

Da ich das ganze per Reflection mache, sieht dazu mein Code so aus:


range = sheet.GetType().InvokeMember("Columns", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, new object[2] { i, Type.Missing });

So, um nun die Spalte zu formatieren verwende ich folgendes:


range.GetType().InvokeMember("NumberFormat", BindingFlags.SetProperty | BindingFlags.OptionalParamBinding, null, range, format);

In format steht zB "0,00", "0", "TT.MM.JJJJ HH:mm:ss".

Tja das wars, leider funktioniert es nur nicht...
Ich hab dann mal was anderes versucht:


range = sheet.GetType().InvokeMember("Cells", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, new object[2] { 2, i });

object entirecolumn = range.GetType().InvokeMember("EntireColumn", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, range, new object[0]);

entirecolumn.GetType().InvokeMember("NumberFormat", BindingFlags.SetProperty | BindingFlags.OptionalParamBinding, null, entirecolumn, format);

Und siehe da, es wird was formatiert. Die Dezimalzahlen werden mit 2 Kommastellen angezeigt, die Zahlen überhaupt als Zahl gespeichert und nicht als Text. Nur ein Manko gibt es noch, und zwar das Datum. Das Datum wird in der ersten Zeile richtig formatiert, in den nächsten Zeilen wird die Zeit abgeschnitten, es wird einfach als Datum formatiert, aber nicht in dem Stil wie ich will ("TT.MM.JJJJ HH:mm:ss").

Jetzt stellt sich die Frage, warum funktioniert das überhaupt, wenn ich anstatt


range = sheet.GetType().InvokeMember("Columns", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, new object[2] { i, Type.Missing });

das hier mache:


range = sheet.GetType().InvokeMember("Cells", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, new object[2] { 2, i });

Das ergibt für mich gar keinen Sinn. Wenn ich mir die Formatierung von Zellen anschaue die leer sind - stimmt sie auch nicht mit der Formatierung die ich bestimmt habe überein, sondern es ist einfach das "Standard" format.

Anbei noch zwei Screenshots zur Variante 1 [2] und 2 [3]. Außerdem hier nochmals der ganze Code:


foreach (DataColumn column in table.Columns) {
    i++;

    // Insert fieldname
    object range = sheet.GetType().InvokeMember("Cells", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, new object[2] { 1, i });
    range.GetType().InvokeMember("Value", BindingFlags.SetProperty | BindingFlags.OptionalParamBinding, null, range, new object[1] { column.ColumnName });

    object[] format = null;
    if(column.DataType.Equals(typeof(double))){
        string s = "0" +
                   System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

        for (int digits = 0; digits < System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalDigits; digits++) {
            s += "0";
        }
        format = new object[] { s.ToString() };
    }else if(column.DataType.Equals(typeof(int))){
        format = new object[] { "0" };
    }else if(column.DataType.Equals(typeof(Int16))){
        format = new object[] { "0" };
    }else if(column.DataType.Equals(typeof(DateTime))){
        format = new object[] { "TT.MM.JJJJ HH:mm:ss" };
    }else if(column.DataType.Equals(typeof(string))){
        format = new object[] { "" };
    }
    //Excel.Range oRange = (Excel.Range)ws.Columns[SpaltenNummer, Type.Missing];
    range = sheet.GetType().InvokeMember("Columns", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, new object[2] { i, Type.Missing });
    //range = sheet.GetType().InvokeMember("Cells", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, new object[2] { 2, i });
    //range.GetType().InvokeMember("EntireColumn", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, range, new object[0]).GetType().InvokeMember("NumberFormat", BindingFlags.SetProperty | BindingFlags.OptionalParamBinding, null, range, format);
    range.GetType().InvokeMember("NumberFormat", BindingFlags.SetProperty | BindingFlags.OptionalParamBinding, null, range, format);
}

lg
Bakunin

[1] http://www.mycsharp.de/wbb2/attachment.php?attachmentid=1541
[2] http://anarxo.homelinux.org/Variante_1.JPG
[3] http://anarxo.homelinux.org/Variante_2.JPG

Hi Leute,

hab was intressantes rausgefunden. Und zwar, Variante 1 ist schon richtig, allerdings wird das ganze im Excel nur falsch dargestellt. Sobald man zB auf die Zelle A2 klickt, und dann ins fx (wie heißt das?!) klickt, und wieder wegklickt auf eine andere Zelle, dann wird das ganze richtig dargestellt. Also vorher steht zB 0 drinnen, oder 2.6133, nach dieser Prozedur dann eben 0,00 oder 2.61.

Aber das kann doch nicht die Lösung sein? Außerdem noch etwas, bei der Datum-Spalte, wenn nache einem Datum ein Leeres Feld kommt, geht die Formatierung für die nächsten Zellen drauf....

Ist das jetzt ein Excel Bug oder liegt es an mir? Die Lösung für das 1 Problem wäre wahrscheinlich (dummy lösung) alle Zellen zu selektieren und wieder zu deselektieren. Aber das kanns doch auch nicht sein?

Hier die Links zu den Screenshots:
Draufklicken -> http://anarxo.homelinux.org/Variante_1_bla.JPG
Und wieder wegklicke tadaa -> http://anarxo.homelinux.org/Variante_1_bla2.JPG

Hier noch meine Insert Prozedur in das Excel Sheet


// write data
foreach (int merkmalNr in m_Messwerte.Keys) {
    cmd.CommandText = "INSERT INTO [Merkmal " + merkmalNr.ToString() + "$] " +
                      "(Wert, Stichprobenumfang, Anzahl_Fehler, Attribut, " +
                      "Datum, Ereignisse, Chargennummer, Nestnummer, " +
                      "Prüfernummer, Maschinennummer, Prozeßparameter, " +
                      "Prüfmittelnummer) " +

                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

    foreach (Messwert m in m_Messwerte[merkmalNr]) {
        //fill parameters
        cmd.Parameters.Add("Wert", OleDbType.Double).Value = m.Wert;
        cmd.Parameters.Add("Stichprobenumfang", OleDbType.Integer).Value = m.Stichprobenumfang;
        cmd.Parameters.Add("Anzahl_Fehler", OleDbType.Integer).Value = m.AnzahlFehler;
        cmd.Parameters.Add("Attribut", OleDbType.SmallInt).Value = m.Attribut;
        if (m.Datum_Zeit != null) {
            cmd.Parameters.Add("Datum", OleDbType.Date).Value = m.Datum_Zeit;
        } else {
            cmd.Parameters.Add("Datum", OleDbType.Date).Value = DBNull.Value;
        }
        cmd.Parameters.Add("Ereignisse", OleDbType.Integer).Value = m.Ereignisse;
        cmd.Parameters.Add("Chargennummer", OleDbType.VarChar).Value = Convert.ToString(m.Chargennummer) + "";
        cmd.Parameters.Add("Nestnummer", OleDbType.VarChar).Value = Convert.ToString(m.Nestnummer) + "";
        cmd.Parameters.Add("Prüfernummer", OleDbType.VarChar).Value = Convert.ToString(m.Prüfernummer) + "";
        cmd.Parameters.Add("Maschinennummer", OleDbType.VarChar).Value = Convert.ToString(m.Maschinennummer) + "";
        cmd.Parameters.Add("Prozeßparameter", OleDbType.VarChar).Value = Convert.ToString(m.Prozeßparameter) + "";
        cmd.Parameters.Add("Prüfmittelnummer", OleDbType.VarChar).Value = Convert.ToString(m.Prüfmittelnummer) + "";

        //execute query
        cmd.ExecuteNonQuery();

        cmd.Parameters.Clear();
    }
}

Vielleicht weiß ja jemand hier wo das Problem liegt...

lg
Bakunin