Announcement

Collapse
No announcement yet.

Visual C# Daten in Excell übertragen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Visual C# Daten in Excell übertragen

    Hallo,

    ich möchte gerne in Visual Studio C# daten (Zahlen) in Excell speichern und öffnen. Da Excell punkte wie z.B. 2.45 nicht erkennt bzw. nicht auswerten kann, soll es vorher automatisch punkt in komma ändern und dann in excell abspeichern. Hat irgendeiner ein Tipp wie man das machen kann?

    Vielen Dank im Voraus

  • #2

    Excel müsste es nicht erkennen, wenn man ihm sagte, was man will. Aber Du kannst die Werte schon beim Schreiben formatieren. Versuch mal value.ToString(CultureInfo.GetCultureInfo("de-DE"));

    Comment


    • #3
      Ich hab folgendes gemacht und weiß ehrlich gesagt nicht so genau, wie ich das mit Cultureinfo einpflegen soll?
      private void dataSave_Button_Click(object sender, EventArgs e)
      {
      // Erstellen eines SaveFileDialog um Speicherort und Dateiname abzufragen
      SaveFileDialog saveFile1 = new SaveFileDialog();

      // Speicherformat wählen
      saveFile1.DefaultExt = "*.rtf";
      saveFile1.Filter = "Text documents (.rtf)|*.rtf";

      // Ermitteln, ob Dateiname eingegeben/ausgewählt wurde
      if (saveFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
      saveFile1.FileName.Length > 0)
      {
      // Inhalt der RichTextBox in Datei sichern
      TextWriter txt = new StreamWriter(saveFile1.FileName);
      txt.Write(serialMonitor.Text);
      txt.Close();
      }
      }

      Comment


      • #4
        Da bist du tatsächlich schon viel zu spät an den Daten unterwegs um sinnvoll noch was zu ändern. Das Detail "ich habe schon was als rtf Tabelle" war nicht ganz unerheblich.
        Das Zahlenformat solltest du zu dem Zeitpunkt lösen wo aus den Zahlen (solange es noch ein Zahlentyp ist und kein string) Zeichenfolgen werden. Also irgendwo bevor du ein rtf hast. Womöglich zu dem Zeitpunkt aus dem aus den Zahlen die rtf Tabelle wird.

        Comment


        • #5
          meinst etwa hier:
          private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
          {
          while (port.IsOpen)
          {
          Thread.Sleep(250);
          var sp = (SerialPort)sender;
          string receivedText = sp.ReadExisting();
          //Console.WriteLine(receivedText);

          Comment


          • #6
            Da hast du doch auch keine Zahlen sondern nur Text der wie Zahlen aussieht. Sorry aber du rückst offensichtlich wichtige Details, auch für dich offensichtlich wenn du dich versuchsweise mal in einen potentiellen Helfer hineinversetzt, nicht einfach so raus. So ist dir kaum zu helfen.

            Bitte denke nochmal genau darüber nach was du da hast was du willst und wie du das jemanden vermitteln musst das er auch eine Chance hat dir zu helfen ohne jedes Detail nachzufragen bzw. ständig versucht in die falsche Richtung zu helfen.

            Comment


            • #7
              Beim Erklärung tue ich mich generell sehr schwierig. So ich versuche es kleinschrittig zu erklären was ich gerne möchte und mache.
              Mein Ziel ist es, Messwerte (die ich mit Visual Studio durchführe) in Excell zu speichern und abzurufen.
              Ich messe drücke (Über-und Unterdruck) mithilfe von drei Sensoren und erfasse gleichzeitig die Messzeit in Millisekunden.
              Die sensoren sind an einem arduino angeschlossen. Mit der Benutzeroberfläche von Visual Studio führe ich die Messung für Über-und Unterdruck durch. Über-und Unterdruck haben jeweils ein Button.
              Mit dem Button Data save speichere ich die Messung als text ab. Leider ist es so, dass die Werte kein Komma haben, sondern Punkt. Mit Punkt lässt sich schlecht eine Auswertung machen. Außerdem kann ich die werte die als text abgespeichert werden nicht einfach in Excell manuell übertragen. Aus diesem grund fände ich besser, wenn ich anstatt Text zu speichern, die daten durch ein Button in excell speichere und gleichzeitig das er die Werte wie z.b. 34.54mbar als 34,54 abspeichert. Dazu möchte ich gerne das die spalten jeweils beschriftet werden mit Sensor 1, Sensor 2, Sensor 3 und Zeit.
              Zurzeit speichert er mir text wie zahlen mit Punkt :-(. Meine Frage ist, wie, wo und was muss ich in mein Code ändern, damit ich wie oben beschrieben eine excell auswertung erhalte?

              Das ist mein Code:

              [HTML
              namespace ArduinoGUI
              {
              public partial class Form1 : Form
              {
              SerialPort port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
              String lastScrollbarValue1 = "0";
              String lastScrollbarValue2 = "0";
              String lastScrollbarValue3 = "0";
              String lastScrollbarValue4 = "0";
              String lastScrollbarValue5 = "0";

              private readonly object _lock = new object();
              private readonly Queue<string> _queue = new Queue<string>();
              private readonly AutoResetEvent _signal = new AutoResetEvent(true);
              Thread chartThread;
              public Form1()
              {
              InitializeComponent();

              var chartArea = chart1.ChartAreas[0];

              chart1.ChartAreas[0].AxisY.Minimum = -250;
              chart1.ChartAreas[0].AxisY.Maximum = 250;
              //chartArea.AxisX.LabelStyle.Enabled = false;
              chart1.ChartAreas[0].CursorX.AutoScroll = true;

              chartArea.AxisX.ScaleView.Zoomable = true;
              //chartArea.AxisX.ScaleView.SizeType = DateTimeIntervalType.Number;
              int position = 0;
              int blockSize = 1000;
              int size = blockSize;
              chartArea.AxisX.ScaleView.Zoom(position, size);

              // disable zoom-reset button (only scrollbar's arrows are available)
              chartArea.AxisX.ScrollBar.ButtonStyle = System.Windows.Forms.DataVisualization.Charting.Sc rollBarButtonStyles.SmallScroll;

              // set scrollbar small change to blockSize (e.g. 100)
              chartArea.AxisX.ScaleView.SmallScrollSize = blockSize;

              chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
              chart1.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
              chart1.MouseWheel += chart1_MouseWheel;



              serialPort_ComboBox.Items.Clear();
              foreach (string s in System.IO.Ports.SerialPort.GetPortNames())
              serialPort_ComboBox.Items.Add(s);
              serialPort_ComboBox.SelectedIndex = 0;


              chartThread = new Thread(chartThredMethod);
              chartThread.Priority = ThreadPriority.Highest;


              }
              //port.Open();


              private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
              {
              port.PortName = serialPort_ComboBox.Text;
              }


              private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
              {
              if (port.IsOpen)
              {
              serialMonitor.Text = port.ReadLine();
              }
              }

              private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
              {
              while (port.IsOpen)
              {
              Thread.Sleep(250);
              var sp = (SerialPort)sender;
              string receivedText = sp.ReadExisting();
              //Console.WriteLine(receivedText);

              serialMonitor.Invoke(new Action(() =>
              {
              serialMonitor.AppendText(receivedText);
              serialMonitor.ScrollToCaret();
              /*
              string[] decimalarray = receivedText.Split(' ');
              if (decimalarray.Length == 4)
              {
              string monitorText = " " + decimalarray[0] + " | " + decimalarray[1] + " | " + decimalarray[2] + " | " + decimalarray[3];
              serialMonitor.AppendText(monitorText);
              serialMonitor.ScrollToCaret();
              }
              */
              }));


              lock (_lock)
              {
              _queue.Enqueue(receivedText);
              }

              // notify the waiting thread

              _signal.Set();
              }
              }



              private void openPortButton_Click(object sender, EventArgs e)
              {
              openPort_Button.Enabled = false;
              closePort_Button.Enabled = true;
              port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler );
              port.Open();

              if (!chartThread.IsAlive)
              chartThread.Start();
              }

              private void closePort_Button_Click(object sender, EventArgs e)
              {
              openPort_Button.Enabled = true;
              closePort_Button.Enabled = false;
              Thread thrThreadClose = new Thread(new ThreadStart(ThreadClose));
              thrThreadClose.Start();
              //chartThread.CancelAsync();
              }

              private void ThreadClose()
              {
              port.Close();
              port.Dispose();
              //chartThread.CancelAsync();
              chartThread.Abort();
              }

              private void dataSave_Button_Click(object sender, EventArgs e)
              {
              // Erstellen eines SaveFileDialog um Speicherort und Dateiname abzufragen
              SaveFileDialog saveFile1 = new SaveFileDialog();

              // Speicherformat wählen
              saveFile1.DefaultExt = "*.rtf";
              saveFile1.Filter = "Text documents (.rtf)|*.rtf";

              // Ermitteln, ob Dateiname eingegeben/ausgewählt wurde
              if (saveFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
              saveFile1.FileName.Length > 0)
              {
              // Inhalt der RichTextBox in Datei sichern
              TextWriter txt = new StreamWriter(saveFile1.FileName);
              txt.Write(serialMonitor.Text);
              txt.Close();
              }
              }
              private void motorSteuerungON_Button_Click(object sender, EventArgs e)
              {
              motorSteuerungON_Button.Enabled = false;
              motorSteuerungOff_Button.Enabled = true;
              if (port.IsOpen)
              port.Write("motorOn");
              }

              private void motorSteuerungOff_Button_Click(object sender, EventArgs e)
              {
              motorSteuerungON_Button.Enabled = true;
              motorSteuerungOff_Button.Enabled = false;

              if (port.IsOpen)
              port.Write("motorOff");
              }

              public void chartThredMethod()
              {
              while (port.IsOpen)
              {
              // wait to be notified
              _signal.WaitOne();
              //Thread.Sleep(50);
              string item = null;

              do
              {
              item = null;

              // fetch the item,
              // but only lock shortly
              lock (_lock)
              {
              if (_queue.Count > 0)
              item = _queue.Dequeue();
              }

              if (item != null)
              {
              int n = 0;
              double sensor1 = 0.0, sensor2 = 0.0, sensor3 = 0.0;
              int time = 0;
              double sensorTemp = 0.0;
              //Console.WriteLine(item);
              string[] decimalarray = item.Split(' ');


              if (decimalarray.Length == 4)
              {
              /*if (Convert.ToDouble(decimalarray[0]) < 250.0)
              sensor1 = Convert.ToDouble(decimalarray[0]);
              if (Convert.ToDouble(decimalarray[1]) < 250.0)
              sensor2 = Convert.ToDouble(decimalarray[1]);
              if (Convert.ToDouble(decimalarray[2]) < 250.0)
              sensor3 = Convert.ToDouble(decimalarray[2]);
              */

              Double.TryParse(decimalarray[0], out sensor1);
              Double.TryParse(decimalarray[1], out sensor2);
              Double.TryParse(decimalarray[2], out sensor3);
              Int32.TryParse(decimalarray[3], out time);//Convert.ToInt32(decimalarray[3]);

              if ((sensor1 / 100) != 0)
              chart1Thread(sensor1 / 100, time);
              // else
              // chart1Thread(sensor1/100, time);
              chart2Thread(sensor2 / 100, time);
              chart3Thread(sensor3 / 100, time);

              sensorTemp = sensor1 / 100;
              }


              }
              }
              while (item != null); // loop until there are items to collect
              }
              }


              ][/HTML]

              Ist es jetzt verständlicher ?

              Comment


              • #8
                Meiner Meinung nach solltest du die Daten in deinem DataReceivedHandler aufbereiten. Dort hast du schon kommentierten Code wo du versucht hast die eingehenden Daten zu zerlegen.
                Am geschicktesten würde ich es finden wenn du dir eine Klasse ausdenkst die deine Daten darstellt. Pro Datenzeile bekommst du ja scheinbar 4 Werte. Also erzeuge eine Klasse die diese 4 Werte darstellt in einem passenden Zahlenformat.

                Das macht die Weiterverarbeitung einfacher (Zahlen als Zahlen zu behandeln gibt dir Optionen) und du kannst die benutzten Zahlenformat besser steuern. Einmal was über den Port ankommt und andermal das was an diversen anderen Stellen wieder rausgehen soll (z.B. bei einen Export) sind dann getrennte Probleme und kann dann explizit gesteuert werden so wie man es braucht.

                Also.
                A.) im DataReceivedHandler die Datenzeile zerlegen und die Daten in eine Instanz der genannte neue Klasse übernehmen. Zum konvertieren bietet sich TryParse an wie du es schon an anderer Stelle benutzt. Du solltest aber auch das Ergebnis von TryParse abfragen ob die konvertierung denn auch funktioniert hat. Das deine Arduino die Daten mit . als Dezimaltrenner sendet ist sicher auf Arduino Seite auch eine Einstellungssache und kann sich ändern. Möglicherweise solltest du das erwartete Format also in deinem Programm einstellbar machen. TryParse hat eine Überladung der man das erwartete Format mitgeben kann.
                B.) Eine Liste führen mit Instanzen dieser neuen Klasse (möglicherweise hast du das schon versucht mit einer von dir geführten Queue die du hier auch benutzen könntest).
                C.) Dort wo du den Export machen möchtest nimm dir die Liste iteriere über die genannte Instanzen der neuen Datenklasse und konvertiere die Daten wieder zu strings. Mit Einstellungen die der Erwartung des Ziels entsprechen. Diese Einstellung solltest du möglicherweise auch Konfigurierbar machen. Da das ganze ja system bzw. kulturabhängig ist. Excel zieht sich die Werte zum Beispiel aus den Ländereinstellungen von Windows. Dort ist der Dezimaltrenner und der Feldtrenner bei tabellarischen Daten definiert.
                D.) Wenn der Export Richtung Excel gedacht ist verstehe ich nicht was da rtf soll? Ohne eine spezielles Excelformat zu benutzen sollte es eher csv sein. Dem Feldtrenner kannst du für das lokale System, wie gesagt den Ländereinstellungen, entnehmen.

                Comment

                Working...
                X