Connect Empty Points in Word Chart - c#

I'm creating a Chart in my C# Application with Word Interop. Inside this graph i have some empty data points. How can i connect the empty points programmatically? I'd like to achieve this but inside code. Can anybode help me? Thank you
Edit:
Here is the Code
Dictionary<DateTime, Dictionary<string, decimal>> visuData = new Dictionary<DateTime, Dictionary<string, decimal>>();
string startTime = null;
string endTime = null; //Variablen für die Zeitspanne, aus der Versuchsdaten abgerufen werden sollen
query = "SELECT MIN(Starttime) AS Starttime, MAX(Starttime) AS Endtime FROM dbo.Table WHERE ID = " + checkBox.Text;
con = new SqlConnection(mtecConnectionString);
cmd = new SqlCommand(query, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
startTime = reader.GetDateTime(0).ToString("yyyy-MM-dd hh:mm:ss.fff");
endTime = reader.GetDateTime(1).ToString("yyyy-MM-dd hh:mm:ss.fff");
}
con.Close(); //Zeitspanne bestimmen
if (startTime == null || endTime == null)
return; //Falls keine Daten vorliegen, wird die Methode beendet
List<string> variables = new List<string>();
query = "SELECT ...";
con = new SqlConnection(#"...");
cmd = new SqlCommand(query, con); //Abfrage für Versuchsdaten und Verbindung zur Datenbank setzen
con.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
if (visuData.ContainsKey(reader.GetDateTime(2)))
{
visuData[reader.GetDateTime(2)].Add(reader.GetString(0),
reader.GetDecimal(1));
}
else
{
visuData.Add(reader.GetDateTime(2), new Dictionary<string, decimal>());
visuData[reader.GetDateTime(2)].Add(reader.GetString(0),
reader.GetDecimal(1));
}
if (!variables.Contains(reader.GetString(0)))
variables.Add(reader.GetString(0));
}
con.Close();
Chart chart = document.InlineShapes.AddChart2(-1, XlChartType.xlLineMarkers, paragraph.Range).Chart;
Microsoft.Office.Interop.Excel.Workbook excelWorkbook = chart.ChartData.Workbook;
excelWorkbook.Application.WindowState = Microsoft.Office.Interop.Excel.XlWindowState.xlMinimized;
Microsoft.Office.Interop.Excel.Worksheet excelWorksheet = excelWorkbook.Worksheets[1];
for(int j = 2; j < variables.Count + 2; j++)
{
excelWorksheet.Cells[1, j].Value = variables[j - 2];
}
int rowIndex = 2;
foreach (DateTime moment in visuData.Keys)
{
excelWorksheet.Cells[rowIndex, 1].Value = moment.ToString("HH:mm:ss");
for(int j = 2; j < variables.Count + 2; j++)
{
if (visuData[moment].ContainsKey(variables[j - 2]))
excelWorksheet.Cells[rowIndex, j].Value = visuData[moment][variables[j - 2]];
}
rowIndex += 1;
}
chart.ChartTitle.Text = "Batch ID " + checkBox.Text;
chart.Refresh();
excelWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
I want to display a few variables over time. So I created a dict with the timestamp as key and another dict as value. Inside this second dict I'm using the key to identify the variable and the value to get the value.
This looks like:
2021-12-02 08:00:00 --> Var 1 : 1
2021-12-02 08:00:00 --> Var 2 : 2
2021-12-02 08:05:00 --> Var 1 : 3
2021-12-02 08:05:00 --> Var 3 : 4
The actual Output is, that I have a chart in the created word document. For Var 3 is the value 0 at 8am displayed but I dont want any value for var 3 at 8 am. Same thing with Var 2...
I hope its more clear now

I found the solution myself.
I added before refreshing the chart folling line:
chart.DisplayBlanksAs = Microsoft.Office.Interop.Word.XlDisplayBlanksAs.xlInterpolated;

Related

Set table style. C# - closed xml

I am looking for a way to apply a table style to the inserted data in an excel file.
I use the library closed xml
How can I do it?
Sample table I want to get
using (XLWorkbook wb = new XLWorkbook(excel))
{ IXLWorksheet ws = wb.Worksheets.Last();
string Qry;
using (SqlCommand cmd = new SqlCommand(Qry, sqlConn))
{
sqlConn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
System.Data.DataTable schemaTable = dr.GetSchemaTable();
int i = 1;
foreach (DataRow rowt in schemaTable.Rows)
{
while (dr.Read())
{
row++;
for (int j = 0; j < dr.FieldCount; j++)
{
if (!dr.IsDBNull(j))
{
switch (dr.GetDataTypeName(j))
{
case "Varchar2":
string s = dr.GetString(j);
if (s.Substring(0, 1) == "=")
s = " " + s;
ws.Cell(row, j + 1).Value = s;
break;
case "nvarchar":
ws.Cell(row, j + 1).Value = dr.GetString(j);
break;
default:
break;
}}}}}}}
Based on the ClosedXML documentation:
// create the Excel workbook
var wb = new XLWorkbook();
// creates the worksheet
var ws = wb.AddWorksheet("Sheet1");
// the range for which you want to add a table style
var range = ws.Range(1, 1, 5, 5);
// create the actual table
var table = range.CreateTable();
// apply style
namesTable.Theme = XLTableTheme.TableStyleLight12;

Empty Dataset with SQLDataAdapter

There are 2 scenarios to check when executing this SQL Select Statement below..
retrieveQuery = "SELECT itemName, itemCategory, itemSubCategory, itemPrice, orders, (orders * itemPrice) as TotalPrice FROM Menu WHERE itemCategory = #selectedCat AND itemSubCategory LIKE '%#selectedSubCat%'";
The 2 fields in the parameterized query are selectedCat and selectedSubCat.
First scenario is when the user selects for only Food and as you can see the DropdownList Value selected is ALL which means to say that the query statement's Where Clause should have only selectedCat = 'Food' and selectedSubCat LIKE '%%' (ALL VALUES OF FIELD 'itemSubCategory' FOUND IN THE SQL TABLE)
Second scenario is when the user selects for only Food and selects the DropdownList Value to be Donut which means to say that the query statement's Where Clause should have only selectedCat = 'Food' and selectedSubCat LIKE '%Donut%'
Upon when the user hits the Export to PDF button, these lines of codes are executed..
I have removed the unnecessary codes
String itemCat = HF_TabListType.Value;
String itemSubCatFood = ddlFood.SelectedValue;
String itemSubCatBeverage = ddlBeverages.SelectedValue;
//Retrieving Data to Populate to Report Table
String strConnString = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
SqlConnection myConn = new SqlConnection(strConnString);
myConn.Open();
SqlDataAdapter da;
DataSet dsPDF = new DataSet();
String retrieveQuery = String.Empty;
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
{
PdfPTable reportTable = new PdfPTable(1);
if (itemCat == "Food" || itemCat == "Beverages")
{
reportTable = new PdfPTable(foodGV.Columns.Count - 1);
}
else if (itemCat == "Combo")
{
reportTable = new PdfPTable(gvCombo1Total.Columns.Count);
}
reportTable.TotalWidth = 1000f;
reportTable.LockedWidth = true;
reportTable.HorizontalAlignment = Element.ALIGN_CENTER;
reportTable.SpacingAfter = 30f;
//For Food and Beverages
String[] headerForFB = { "No.", "Item Name", "Item Category", "Item Sub Category", "Item Price($)", "Orders", "Total($)" };
//Fod Combo
String[] headerForC = { "No.", "Combo", "Total Amount of Orders", "Total Discounts($)", "Total Sales($)" };
if (itemCat == "Food" || itemCat == "Beverages")
{
for (int i = 0; i < headerForFB.Length; i++)
{
PdfPCell hCell = new PdfPCell(new Phrase(headerForFB[i].ToString(), BoldFontForHeader));
hCell.FixedHeight = 25f;
reportTable.AddCell(hCell);
}
}
else if (itemCat == "Combo")
{
for (int i = 0; i < headerForC.Length; i++)
{
PdfPCell hCell = new PdfPCell(new Phrase(headerForC[i].ToString(), BoldFontForHeader));
reportTable.AddCell(hCell);
}
}
retrieveQuery = "SELECT itemName, itemCategory, itemSubCategory, itemPrice, orders, (orders * itemPrice) as TotalPrice FROM Menu WHERE itemCategory = #selectedCat AND itemSubCategory LIKE '%#selectedSubCat%'";
da = new SqlDataAdapter(retrieveQuery.ToString(), myConn);
da.SelectCommand.Parameters.AddWithValue("#selectedCat", itemCat);
//da.SelectCommand.Parameters.AddWithValue("selectedSubCat", "%" + itemSubCatFood + "%");
if (HF_TabListType.Value.ToString() == "Food")
{
if (ddlFood.SelectedIndex != 0)
{
da.SelectCommand.Parameters.AddWithValue("#selectedSubCat", itemSubCatFood);
}
else
{
da.SelectCommand.Parameters.AddWithValue("#selectedSubCat", "%%");
}
}
else if (HF_TabListType.Value.ToString() == "Beverages")
{
if (ddlBeverages.SelectedIndex != 0)
{
da.SelectCommand.Parameters.AddWithValue("#selectedSubCat", itemSubCatBeverage);
}
else
{
da.SelectCommand.Parameters.AddWithValue("#selectedSubCat", "%%");
}
}
da.Fill(dsPDF);
GridView1.DataSource = dsPDF;
GridView1.DataBind();
PdfPCell cell = null;
PdfPCell cellCount = null;
int j = 0;
//Food/Beverages
if (dsPDF != null || dsPDF.Tables.Count != 0 || dsPDF.Tables[0].Rows.Count != 0)
{
foreach (DataRow r in dsPDF.Tables[0].Rows)
{
cellCount = new PdfPCell(new Phrase((j + 1).ToString(), NormalFont));
cellCount.FixedHeight = 15f;
reportTable.AddCell(cellCount);
for (int i = 0; i < dsPDF.Tables[0].Columns.Count; i++)
{
cell = new PdfPCell(new Phrase(r[i].ToString(), NormalFont));
cell.FixedHeight = 15f;
reportTable.AddCell(cell);
}
j++;
}
}
When the PDF is generated the output of the PDF Table gives this..
Using the Second Scenario stated above,
I have tried to amend the codes and in some instances i got 2 rows with cells that are empty. Meaning the Dataset produced has the rows and columns needed to set the number of rows and columns of the PDF Table respectively.
Could there be an issue with the Retrieve Statement? Or because of adding the da.SelectCommand.Parameters line into if else statements?
I have been trying to work this out for days..
Appreciate any help please, thanks!

Saving data from SQL query in excel in C# console app

I have a c# program.cs code which is created to save results from sql query to xls file, the problem is that I have two sql query and there are two result sets which need to written to the excel file, I am able to write the 1st result through the below code but not able to write the second result, can you please help on this? Please see my code below, I am using same code block for both the queries but always seem to get results from 1st query.
static void Main(string[] args)
{
//SqlConnection cnn;
//string connectionstring = null;
string connectionstring = "Integrated Security = SSPI;Initial Catalog=Database; Data Source=<Instance Name>;";
string sql1 = null;
string sql2 = null;
string data = null;
string data1 = null;
int i = 0;
int j = 0;
string Filename = #"E:\file\testfile.xls";
if (!File.Exists(Filename))
{
File.Create(Filename).Dispose();
using (TextWriter tw = new StreamWriter(Filename))
{
tw.WriteLine("The very first line!");
tw.Close();
}
}
////*** Preparing excel Application
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
///*** Opening Excel application
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(Filename);
xlWorkSheet = (Excel.Worksheet)(xlWorkBook.ActiveSheet as Excel.Worksheet);
xlApp.DisplayAlerts = false;
SqlConnection conn = new SqlConnection(connectionstring);
//cnn = new SqlConnection(connectionstring);
conn.Open();
////** Write your Sql Query here
sql1 = "Select top 5 DocumentId, DocFileName from <table> order by CreateDate desc";
sql2 = "Select top 5 DocID, Title from <Table> order by CreateDate desc";
///*** Preparing to retrieve value from the database
SQL.DataTable dtable = new SQL.DataTable();
SqlDataAdapter dscmd = new SqlDataAdapter(sql1, conn);
SQL.DataSet ds = new SQL.DataSet();
dscmd.Fill(dtable);
////*** Generating the column Names here
string[] colNames = new string[dtable.Columns.Count];
int col = 0;
foreach (SQL.DataColumn dc in dtable.Columns)
colNames[col++] = dc.ColumnName;
char lastColumn = (char)(65 + dtable.Columns.Count - 1);
xlWorkSheet.get_Range("A1", lastColumn + "1").Value2 = colNames;
xlWorkSheet.get_Range("A1", lastColumn + "1").Font.Bold = true;
xlWorkSheet.get_Range("A1", lastColumn + "1").VerticalAlignment
= Excel.XlVAlign.xlVAlignCenter;
/////*** Inserting the Column and Values into Excel file
for (i = 0; i <= dtable.Rows.Count - 1; i++)
{
for (j = 0; j <= dtable.Columns.Count - 1; j++)
{
data = dtable.Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 2, j + 1] = data;
xlWorkBook.Save();
}
}
//Enter new block in Excel -- for the second query, I need help here below
SQL.DataTable dtable1 = new SQL.DataTable();
SqlDataAdapter dscmd1 = new SqlDataAdapter(sql2, conn);
SQL.DataSet ds1 = new SQL.DataSet();
dscmd1.Fill(dtable1);
////*** Generating the column Names here
string[] colNames1 = new string[dtable1.Columns.Count];
int col1 = 0;
foreach (SQL.DataColumn dc in dtable1.Columns)
colNames1[col1++] = dc.ColumnName;
char lastColumn1 = (char)(68 + dtable1.Columns.Count - 1);
xlWorkSheet.get_Range("D1", lastColumn1 + "1").Value2 = colNames1;
xlWorkSheet.get_Range("D1", lastColumn1 + "1").Font.Bold = true;
xlWorkSheet.get_Range("D1", lastColumn1 + "1").VerticalAlignment
= Excel.XlVAlign.xlVAlignCenter;
/////*** Inserting the Column and Values into Excel file
for (i = 0; i <= dtable1.Rows.Count - 1; i++)
{
for (j = 0; j <= dtable1.Columns.Count - 1; j++)
{
data1 = dtable1.Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 2, j + 1] = data1;
xlWorkBook.Save();
}
}
//end of block
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
}
Image from Excel result

How to convert datatype before Importing Excel file to Sql database

Here I have this Import from excel file to sql database class. It was working correctly till now but as my excel file cells are all strings type , So when Importing , the datatype does not match as sql database. How to convert it to their respective datatype before importing?
public static void ImportToSql(string excelfilepath)
{
string myexceldataquery = "select LocalSKU,ItemName, QOH,Price,Discontinued,Barcode,Integer2,Integer3,SalePrice,SaleOn,Price2 from [sheet1$]";
try
{
string sexcelconnectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source =" + excelfilepath + "; Extended Properties=\"Excel 12.0; HDR=Yes; IMEX=2\"";
string ssqlconnectionstring = "Data Source=DELL\\SQLSERVER1;Trusted_Connection=True;DATABASE=Test;CONNECTION RESET=FALSE";
SqlConnection sqlconn = new SqlConnection(ssqlconnectionstring);
//series of commands to bulk copy data from the excel file into our sql table
OleDbConnection oledbconn = new OleDbConnection(sexcelconnectionstring);
OleDbCommand oledbcmd = new OleDbCommand(myexceldataquery, oledbconn);
oledbconn.Open();
OleDbDataReader dr = oledbcmd.ExecuteReader();
SqlCommand sqlcmd = new SqlCommand(#"MERGE Inventory AS target
USING (select LocalSKU,ItemName, QOH,Price,Discontinued,Barcode,Integer2,Integer3,SalePrice,SaleOn,Price2 from #source) as source
ON (source.LocalSKU = target.LocalSKU)
WHEN MATCHED THEN
UPDATE SET ItemName=source.ItemName,Price=source.Price,Discontinued=source.Discontinued,Barcode=source.Barcode,Integer2=source.Integer2,Integer3 = source.QOH,SalePrice=source.SalePrice,SaleOn=source.SaleOn,Price2=source.Price2;", sqlconn);
SqlParameter param;
param = sqlcmd.Parameters.AddWithValue("#source",dr);
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.InventoryType";
sqlconn.Open();
sqlcmd.ExecuteNonQuery();
sqlconn.Close();
while (dr.Read())
{
}
oledbconn.Close();
Console.WriteLine(".xlsx file imported succssessfully into database.");
}
The easiest thing to do would be to convert them in your SQL statement by using CAST:
SqlCommand sqlcmd = new SqlCommand(
#"MERGE Inventory AS target
USING (select LocalSKU, ItemName, QOH = CAST(QOH AS int)
, Price = CAST(Price AS decimal(10,2)), Discontinued = CAST(Discontinued AS bit)
, Barcode, Integer2 = CAST(Integer2 AS int)
, Integer3 = CAST(Integer3 AS int), SalePrice = CAST(SalePrice AS decimal(10,2))
, SaleOn, Price2 = CAST(Price2 AS decimal(10,2)) from #source) as source
ON (source.LocalSKU = target.LocalSKU)
WHEN MATCHED THEN
UPDATE (. . . )
I'm guessing on some of the conversions, but you get the idea. You'll need to make sure that the data in the spreadsheet all match the datatypes you want to convert them to, as one mistake will cause the whole statement to fail. Something more robust will take a lot more code.
First browse the excel file and put data in datagrid and then read datagrid row one by one.
i give you 2 function for that. one is browse the excel file and put data in datagrid and second one is read datagrid and put record in database
Excel Export Function
private void export_btn_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application ExcelApp =
new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook ExcelBook;
Microsoft.Office.Interop.Excel._Worksheet ExcelSheet;
int i = 0;
int j = 0;
//create object of excel
ExcelBook = (Microsoft.Office.Interop.Excel._Workbook)ExcelApp.Workbooks.Add(1);
ExcelSheet = (Microsoft.Office.Interop.Excel._Worksheet)ExcelBook.ActiveSheet;
//export header
for (i = 1; i <= this.dataGridView1.Columns.Count; i++)
{
ExcelSheet.Cells[1, i] = this.dataGridView1.Columns[i - 1].HeaderText;
}
//export data
for (i = 1; i <= this.dataGridView1.RowCount; i++)
{
for (j = 1; j <= dataGridView1.Columns.Count; j++)
{
ExcelSheet.Cells[i + 1, j] = dataGridView1.Rows[i - 1].Cells[j - 1].Value;
}
}
ExcelApp.Visible = true;
//set font Khmer OS System to data range
Microsoft.Office.Interop.Excel.Range myRange = ExcelSheet.get_Range(
ExcelSheet.Cells[1, 1],
ExcelSheet.Cells[this.dataGridView1.RowCount + 1,
this.dataGridView1.Columns.Count]);
Microsoft.Office.Interop.Excel.Font x = myRange.Font;
x.Name = "Arial";
x.Size = 10;
//set bold font to column header
myRange = ExcelSheet.get_Range(ExcelSheet.Cells[1, 1],
ExcelSheet.Cells[1, this.dataGridView1.Columns.Count]);
x = myRange.Font;
x.Bold = true;
//autofit all columns
myRange.EntireColumn.AutoFit();
ExcelApp.ActiveWorkbook.SaveCopyAs("E:\\reports.xlsx");
ExcelApp.ActiveWorkbook.Saved = true;
ExcelApp.Quit();
MessageBox.Show("Excel file created,you can find the file E:\\reports.xlsx");
//
ExcelSheet = null;
ExcelBook = null;
ExcelApp = null;
}
Read Datagrid
public void readDataGrid()
{
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
try
{
//Here read one by one cell and convert it into your required datatype and store it in
String rowcell1 = dataGridView1.Rows[i].Cells[0].Value.ToString();
}
catch (Exception err)
{
}
count++;
}
}
I this is help you.

convert datetime to string in sql select query

I am trying to display data from database on datagriview and export data from data grid view to csv, my sqlite database dateformat is DateTime
2012-02-20 16:42:10.000
displayed on datagridview is in the format of
20/02/2012 16:42:10
my select statment is , i want to display on datagridview datetime column as the same format which in database
m_dbConnection.Open();
SQLiteCommand myCommand = new SQLiteCommand();
myCommand.Connection = m_dbConnection;
myCommand.CommandText = "select CompanyId,CONVERT(VARCHAR,DateTime, 103) as date_issued,Serial,ShortDeviceId,MatricolaA,Upper(Targa),VerbaliRuleOnePoints,VerbaliMissedNotificationDescription from VerbaliData";
//myCommand.Connection = myConn;
DataTable data = new DataTable();
SQLiteDataAdapter myAdapter = new SQLiteDataAdapter(myCommand);
//myAdapter.SelectCommand = myCommand;
myAdapter.Fill(data);
dataGridView1.DataSource = data;
this.dataGridView1.Refresh();
if (dataGridView1.RowCount > 0)
{
string value = "";
DataGridViewRow dr = new DataGridViewRow();
StreamWriter swOut = new StreamWriter("I:/final test/finaltest12.csv");
//write header rows to csv
for (int i = 0; i <= dataGridView1.Columns.Count - 1; i++)
{
if (i > 0)
{
swOut.Write(",");
}
swOut.Write(dataGridView1.Columns[i].HeaderText);
}
swOut.WriteLine();
//write DataGridView rows to csv
for (int j = 0; j <= dataGridView1.Rows.Count - 1; j++)
{
if (j > 0)
{
swOut.WriteLine();
}
dr = dataGridView1.Rows[j];
for (int i = 0; i <= dataGridView1.Columns.Count - 1; i++)
{
if (i > 0)
{
swOut.Write(",");
}
// Datetime column content transformed in a formatted string....
if(i == 1)
{
object cellValue = dr.Cells[i].Value;
value = (cellValue == DBNull.Value ?
string.Empty : Convert.ToDateTime(cellValue).ToString("DD-MM-YYYY hh:mm:ss"));
}
value = dr.Cells[i].Value.ToString();
//replace comma's with spaces
value = value.Replace(',', ' ');
//replace embedded newlines with spaces
value = value.Replace(Environment.NewLine, " ");
swOut.Write(value);
}
}
swOut.Close();
}
m_dbConnection.Close();
}
You can use Dataformatstring
Add Dataformatstring like
Dataformatstring="yyyy-MM-dd HH:mm:ss.s" in bound field column
The easiest way is to not cast your DateTime object to a string in your SQL statement:
myCommand.CommandText = "select CompanyId, date_issued, Serial, ShortDeviceId, " +
"MatricolaA, Upper(Targa), VerbaliRuleOnePoints, VerbaliMissedNotificationDescription " +
"from VerbaliData";
I don't think "Upper(Targa)" is going to work, though.
Whatever, right? That's not the issue here.
Once you're done with that, handle your DateTime object in your code as you are parsing through the data:
if (i == 1)
{
object cellValue = dr.Cells[i].Value;
value = (cellValue == DBNull.Value) ?
string.Empty :
Convert.ToDateTime(cellValue).ToString("DD-MM-YYYY hh:mm:ss");
}
I hope that helps.

Categories