背景:我正在为大学建立一个项目,编程并不是我的“专业领域”。这是一个基于 C#(Visual Studio)构建的 GUI。问题:我尝试制作一个数据记录器,它应该记录用户所做的一切(以及时间戳)并将其保存在 .csv 文件中,但我似乎无法让程序创建它。一旦我关闭应用程序,它应该出现在我的桌面上,并记录我所做的事情。如果这里有人可以检查一下并“看看它是否有意义”,也许指出它哪里错了,那就太好了。
PD:抱歉,英语不是我的母语。
这是我认为存在错误的代码:
using ClosedXML.Excel;
using DocumentFormat.OpenXml.Drawing.Diagrams;
namespace Proyecto_controlLed_Servo
{
public partial class Form1 : Form
{
private List<string> receivedDataList = new List<string>();
private bool _isRunning = true;
public Form1()
{
CheckForIllegalCrossThreadCalls = false;
receivedDataList = new List<string>();
SP1.DataReceived += new SerialDataReceivedEventHandler(SP1_DataReceived);
SP1.ErrorReceived += new SerialErrorReceivedEventHandler(SP1_ErrorReceived);
SP1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
LogAlert("Aplicación iniciada");
}
private void bCon_Click(object sender, EventArgs e)
{
try
{
if (!SP1.IsOpen)
{
SP1.PortName = CBPort.Text;
SP1.Open();
LogAlert("Conexión Establecida");
receivedDataList.Add("Conexión al puerto COM establecida.");
PBConexion.Value = 100;
enableComponents();
}
}
catch (Exception error)
{
MessageBox.Show("Error al conectarse al puerto: " + error.Message);
}
}
private void bDis_Click(object sender, EventArgs e)
{
if (SP1.IsOpen)
{
try
{
//Enviar comando para apagar steppers y cerrar puerto COM
SP1.WriteLine("l");
SP1.Close();
LogAlert("Gimb-App desconectado");
receivedDataList.Add("Se ha desconectado del puerto COM.");
MessageBox.Show("Entrada COM desconectada");
PBConexion.Value = 0;
labelEstado.Text = "Estado actual: Desconectado";
}
catch (Exception error)
{
MessageBox.Show("Error al desconectar el puerto: " + error.Message);
}
}
}
private void BRef_Click(object sender, EventArgs e)
{
try
{
string[] ports = SerialPort.GetPortNames();
CBPort.Items.Clear();
CBPort.Items.AddRange(ports);
if (ports.Length > 0)
{
CBPort.SelectedIndex = 0;
}
MessageBox.Show("Lista de puertos actualizada");
receivedDataList.Add("Se refrescó la lista de puertos COM.");
}
catch (Exception error)
{
MessageBox.Show("Error al refrescar la lista de puertos: " + error.Message);
}
}
//Método para registrar alertas
private void LogAlert(string message)
{
string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
receivedDataList.Add($"{timestamp}:{message}");
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (SP1.IsOpen)
{
try
{
SP1.WriteLine("l");
SP1.Close();
}
catch (Exception error)
{
MessageBox.Show("Error al cerrar la aplicación: " + error.Message);
}
}
_isRunning = false;
SaveDataToCsv();
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
if (!_isRunning) return;
try
{
string data = SP1.ReadLine();
receivedDataList.Add("Dato recibido: " + data);
Console.WriteLine("Dato recibido: " + data);
}
catch (Exception error)
{
receivedDataList.Add("Error al recibir datos: " + error.Message);
}
}
private void SaveDataToCsv()
{
try
{
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filePath = Path.Combine(desktopPath, "RegistroGimb.csv");
string csvFilePath = Path.ChangeExtension(filePath, ".csv");
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add("Registros");
worksheet.Cell(1, 1).Value = "Registro de Actividades";
for (int i = 0; i < receivedDataList.Count; i++)
{
worksheet.Cell(i + 2, 1).Value = receivedDataList[i];
}
workbook.SaveAs("RegistroGimb.xlsx"); //guardar como archivo .xlsx
}
ConvertXlsxToCsv(filePath, csvFilePath);
MessageBox.Show("Registro de alertas guardado en {filePath}");
}
catch (Exception error)
{
MessageBox.Show("Error al escribir en el archivo de registro: " + error.Message);
}
}
private void ConvertXlsxToCsv(string filePath, string csvFilePath)
{
try
{
using (var workbook = new XLWorkbook(filePath))
{
var worksheet = workbook.Worksheet(1);
using (var writer = new StreamWriter(csvFilePath))
{
foreach (var row in worksheet.RowsUsed())
{
var cells = row.CellsUsed().Select(c => c.GetValue<string>());
var line = string.Join(",", cells);
writer.WriteLine(line);
}
}
}
}
catch (Exception error)
{
MessageBox.Show("Error al convertir el archivo a CSV: " + error.Message);
}
}
//Método para lectura de puerto serie
private void SP1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
string data = SP1.ReadLine();
if (data.Contains("Movimiento detectado"))
{
LogAlert("Movimiento detectado");
}
else if (data.Contains("Motor endendido"))
{
LogAlert("Motor encendido");
}
else if (data.Contains("Motor apagado"))
{
LogAlert("Motor apagado");
}
else if (data.Contains("Conexión establecida"))
{
LogAlert("Conexión establecida");
}
else if (data.Contains("Desconexion"))
{
LogAlert("Desconexión del puerto COM");
}
else
{
LogAlert("Dato recibido: " + data);
}
}
catch (Exception error)
{
MessageBox.Show("Error al leer datos del puerto serie: " + error.Message);
LogAlert("Error al leer datos del puerto serie: " + error.Message);
}
}
我发现了一些问题。首先,从小事做起,而不是试图解决“完整”的问题。如果你想保存一个 CSV 文件,它只是一个逗号分隔的文件,所以不需要创建 Excel 文档。你在那里介绍的步骤只会让你迷失方向。例如,你正在创建 Excel 文档并通过以下方式保存它:
...但随后您想将其转换为您正在传递的 CSV:
请注意,“filePath”不是您保存 XLSX 的文件名,并且可能不在桌面文件夹中。默认情况下,文件将保存在工作文件夹中,该文件夹通常与您的应用程序正在运行的文件夹相同。
以最简单的方式保存 CSV 就像打开文件阅读器并用逗号分隔的任意值写入行一样简单。由于您的“警报”是单个字符串,因此这非常简单:
这会将输出写入桌面上的 CSV。每次运行时都会覆盖任何现有的 RegistroGimb.csv 文件。您可以检查文件是否存在,并将其附加
AppendAllText
到现有文件中。无需处理 Excel 文档。Excel 将识别并打开 CSV 文件。