How to convert table format to string programmatically - c#

Good day all,
would like request to how to convert table format to string
eg:
Material Control August
Development September
Planning August
HR September
to
September: Development, HR
August : Material Control, Planning
List<String> returnvalueStringMonth = new List<String>();
List<String> returnvalueStringDept = new List<String>();
foreach (DataRow dr in dsSeries.Tables[0].Rows)
{
string newmanout = dr["MonthNames"].ToString();
returnvalueStringMonth.Add(newmanout);
string Departs = dr["Depart"].ToString();
returnvalueStringMonth.Add(Departs);
//var DDLName = dr["Depart"];
//Label dynamicLabel = new Label();
//dynamicLabel.Text = DDLName.ToString() + ",";
//div1.Controls.Add(dynamicLabel);
//var sumPlus = Convert.ToDouble(newmanout) +",";
}
List<string> b = new List<string>();
b.AddRange(returnvalueStringMonth.Distinct());
for (int cs = 0; cs < b.Count; cs++)
{
//Panel aspPanel = new Panel();
Label dynamicLabel = new Label();
dynamicLabel.Text = b[cs].ToString()+":" + "<br/>";
div1.Controls.Add(dynamicLabel);
}
I able achive until month only, then i realize made mistake.
So, please advise how to achive this.

The code below will fill a list of strings with your desired output. You can change the second loop to do what you want.
var monthList = new Dictionary<String, List<String>>();
foreach (DataRow dr in dsSeries.Tables[0].Rows)
{
var key = dr["MonthName"].ToString();
var value = dr["Department"].ToString();
if (!monthList.ContainsKey(key))
{
monthList.Add(key, new List<string>());
}
monthList[key].Add(value);
}
List<string> b = new List<String>();
foreach (var month in monthList.Keys)
{
b.Add(month + ": " + String.Join(", ", monthList[month])");
}
If you would rather use LINQ, you can do this instead:
var q = from row in dsSeries.Tables[0].AsEnumerable()
group row by row["Month"] into qGrouped
orderby qGrouped.Key
select String.Format("{0}: {1}", qGrouped.Key,
String.Join(", ", Array.ConvertAll(qGrouped.ToArray(), r => r["Department"])));
var b = q.ToList();

public class TestClass
{
public string S1 { get; set; }
public string S2 { get; set; }
}
[TestMethod]
public void MyTest()
{
// Material Control August
//Development September
//Planning August
//HR September
var list = new List<TestClass>
{
new TestClass {S1 = "Material Control", S2 = "August"},
new TestClass {S1 = "Development", S2 = "September"},
new TestClass {S1 = "Planning", S2 = "August"},
new TestClass {S1 = "HR", S2 = "September"}
};
var listGroupByMonth = list.GroupBy(l => l.S2);
foreach (var lstByMonth in listGroupByMonth)
{
var key = lstByMonth.Key;
var finalValue = string.Join(", ", lstByMonth.ToList().Select(lbm => lbm.S1));
}
}

Related

Change for loop to forEach

I am working on a inventory updating program in vs2022 which I am using Gembox Spreadsheet for, It is working right now, but the boss man would like me to try to convert my for loop to a for each loop. The loop is what I am using to update my file.
Current For Loop
public void updateFile(string filename, int range, ItemLine selectedItem, decimal outValue)
{
var fullPath = $".\\Backend Files\\{filename}";
SpreadsheetInfo.SetLicense("FREE -LIMITED-KEY");
var workbook = ExcelFile.Load(fullPath, new CsvLoadOptions(CsvType.CommaDelimited));
var worksheet = workbook.Worksheets[0];
//foreach (var row in worksheet.Rows.Skip(1))
//{
// foreach (var cell in row.AllocatedCells)
// {
// string updateValue =
// if(cell.Value == int.TryParse((int)outValue, out int updateValue))
// {
// }
// }
//}
for (int i = 1; i <= range; i++)
{
var plan = worksheet.Rows[i].Cells[0].Value;
var desc = worksheet.Rows[i].Cells[1].Value;
var csvDescription = plan + " - " + desc;
var platedescription = plan + " - ";
if (selectedItem.ComboDescription == csvDescription)
{
worksheet.Rows[i].Cells[2].Value = selectedItem.Quantity;
}
if (selectedItem.plateDescription == platedescription)
{
worksheet.Rows[i].Cells[1].Value = selectedItem.Quantity;
}
}
workbook.Save(fullPath, new CsvSaveOptions(CsvType.CommaDelimited));
}
I beleive the forEach would look similar to this
private static List<ItemLine> ReadFile(string fileName, string defaultValueDescription)
{
string path = $".\\Backend Files\\{fileName}";
SpreadsheetInfo.SetLicense("FREE -LIMITED-KEY");
var workbook = ExcelFile.Load(path, new CsvLoadOptions(CsvType.CommaDelimited));
var worksheet = workbook.Worksheets[0];
var items = new List<ItemLine>();
items.Add(new ItemLine { Description = defaultValueDescription, Quantity = 0 });
foreach (var row in worksheet.Rows.Skip(1))
{
var cells = row.AllocatedCells;
var il = new ItemLine();
if (cells.Count == 2)
{
il.Description = cells[0].Value?.ToString() ?? "Description Not Found";
il.Quantity = cells[1].IntValue;
}
else if (cells.Count >= 3)
{
il.Plan = cells[0].Value?.ToString() ?? "Plan Not Found";
il.Description = cells[1].Value?.ToString() ?? "Description Not Found";
il.Quantity = cells[2].IntValue;
}
items.Add(il);
}
return items;
}

add two group into one group in c#

I have two groups like below, theyh have different data. Based on both I need to create an xml file .
How can I write a for-loop for both groups and generate a single xml file?
var groups = checkFile.AsEnumerable().GroupBy(x => new { DocNum = x.Field<int>("orderid"), Type = x.Field<string>("Type"), ProdName = x.Field<string>("ProdName"), Status = x.Field<string>("Status"), productno = x.Field<string>("productno"), uom = x.Field<string>("uom"), customer = x.Field<string>("customer"), remark = x.Field<string>("remark"), U_JobNumber = x.Field<string>("U_JobNumber"), U_SalesPerson = x.Field<string>("U_SalesPerson"), U_POnum = x.Field<string>("U_POnum"), U_JobType = x.Field<string>("U_JobType"), PlannedQty = x.Field<decimal>("PlannedQty"), OriginNum = x.Field<int?>("OriginNum"), orderdate = x.Field<DateTime>("orderdate"), duedate = x.Field<DateTime>("duedate"), DocTotal = x.Field<decimal>("DocTotal") });
var groups2 = checkFile2.AsEnumerable().GroupBy(x => new { DocNum = x.Field<int>("DocNum") });
//now i need to take both group data inside this loop to print the file
foreach (var group in groups)
{
var stringwriter = new StringWriter();
using (var xmlWriter = XmlWriter.Create(stringwriter, new XmlWriterSettings { Indent = true }))
{
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement("Root");
xmlWriter.WriteEndElement();
}
var xml = stringwriter.ToString();
XmlDocument docSave = new XmlDocument();
docSave.LoadXml(stringwriter.ToString());
docSave.Save(System.IO.Path.Combine(#SystemSettings.ImportBankStatementPendingFolderPath, "DocNum -" + group.Key.DocNum + ".xml"));
count++;
}
Try following :
DataTable checkFile = new DataTable();
var groups = checkFile.AsEnumerable().GroupBy(x => new
{
DocNum = x.Field<int>("orderid"),
Type = x.Field<string>("Type"),
ProdName = x.Field<string>("ProdName"),
Status = x.Field<string>("Status"),
productno = x.Field<string>("productno"),
uom = x.Field<string>("uom"),
customer = x.Field<string>("customer"),
remark = x.Field<string>("remark"),
U_JobNumber = x.Field<string>("U_JobNumber"),
U_SalesPerson = x.Field<string>("U_SalesPerson"),
U_POnum = x.Field<string>("U_POnum"),
U_JobType = x.Field<string>("U_JobType"),
PlannedQty = x.Field<decimal>("PlannedQty"),
OriginNum = x.Field<int?>("OriginNum"),
orderdate = x.Field<DateTime>("orderdate"),
duedate = x.Field<DateTime>("duedate"),
DocTotal = x.Field<decimal>("DocTotal")
});
DataTable checkFile2 = new DataTable();
//now i need to take both group data inside this loop to print the file
foreach (var group in groups)
{
List<DataRow> groups2 = checkFile2.AsEnumerable().Where(x => group.Key.DocNum == x.Field<int>("DocNum")).ToList();
}

Linq Expression works on Desktop but errors on Server

This is the strangest thing I've ever seen, but hopefully someone else has because I am clueless. I have the following code:
DataTable dt = (DataTable)dataGridView1.DataSource;
List<InvoiceItem> itemList = new List<InvoiceItem>();
int listSize = 30;
int listIndex = 0;
try
{
itemList = (from DataRow dr in dt.Rows
select new InvoiceItem()
{
CustomerRef = dr["CustomerRef"].ToString(),
Description = dr["Description"].ToString(),
ItemRef = dr["ItemRef"].ToString(),
Rate = Convert.ToDouble(dr["Rate"].ToString()),
Quantity = Convert.ToDouble(dr["Quantity"].ToString()),
PONumber = dr["PONumber"].ToString(),
UnitOfMeasure = dr["UnitOfMeasure"].ToString(),
RefNumber = dr["RefNumber"].ToString(),
Total = Convert.ToDouble(dr["Total"].ToString()),
Address1 = dr["Address1"].ToString(),
Address2 = dr["Address2"].ToString(),
Address3 = dr["Address3"].ToString(),
Address4 = dr["Address4"].ToString(),
City = dr["City"].ToString(),
State = dr["State"].ToString(),
PostalCode = dr["PostalCode"].ToString(),
ServiceDate = string.IsNullOrEmpty(dr["ServiceDate"].ToString()) ? (DateTime?)null : DateTime.Parse(dr["ServiceDate"].ToString()),
TxnDate = string.IsNullOrEmpty(dr["TxnDate"].ToString()) ? DateTime.Now : DateTime.Parse(dr["TxnDate"].ToString()),
Note = dr["Note"].ToString()
}).ToList();
List<string> list = new List<string>();
list = loadItems();
List<InvoiceItem> createNewItemsList = new List<InvoiceItem>();
foreach (var importing in itemList)
{
var matchingvalues = list.Where(l => l.Contains(importing.ItemRef));
//If there is no match in Quickbooks already...
if (matchingvalues.Count() < 1)
{
createNewItemsList.Add(new InvoiceItem
{
ItemRef = importing.ItemRef,
UnitOfMeasure = importing.UnitOfMeasure
});
}
}
Here is the Code for loadItems():
private List<string> loadItems()
{
string request = "ItemQueryRq";
connectToQB();
int count = getCount(request);
IMsgSetResponse responseMsgSet = sessionManager.processRequestFromQB(BuildItemQuery());
string[] itemList = parseItemQueryRs(responseMsgSet, count);
disconnectFromQB();
List<string> list = new List<string>(itemList);
return list;
}
Here is a view of the error:
here shows list count:
When I run this code on my deskotp, if matchingvalues.Count() = 0 it executes the code correctly. However, when I run the exact same code in debug on the server, that line of code errors out with "Object reference not set to an instance of an object." Can anybody explain why this might happen and if there is any work around for it?

Alternate foreach output

I have this code which grabs the specified text from a webpage:
static void Main(string[] args)
{
using (var client = new WebClient())
{
var pageContent = client.DownloadString("http://www.modern-railways.com");
var regexTitle = new Regex(#"<span class='articleTitle'>(.+?)</span>");
var regexDate = new Regex(#"class='summaryText' data-ajax='false'>(.+?)</a></p><div");
foreach (Match title in regexTitle.Matches(pageContent))
{
var articleTitle = title.Groups[1].Value;
Console.WriteLine(articleTitle);
}
foreach (Match date in regexDate.Matches(pageContent))
{
var articleDate = date.Groups[1].Value;
Console.WriteLine(articleDate);
}
Console.ReadLine();
}
}
As it is now it prints all the articleTitle first and then all the articleDate. How can I get out 1st line ArticleTitle, second line articleDate and so on?
You can use LINQ and Zip method:
var titles = regexTitles.Matches(pageContent).Cast<Match>();
var dates = regexDate.Matches(pageContent).Cast<Match>();
var source = titles.Zip(dates, (t, d) => new { Title = t, Date = d })
foreach (var item in source)
{
var articleTitle = item.Title.Groups[1].Value;
var articleDate = item.Date.Groups[1].Value;
Console.WriteLine(articleTitle);
Console.WriteLine(articleDate);
}

Multiple Array Insertion in C# using Foreach statement

private void Updated_ModRecFGA()
{
try
{
DRFGAModifiedRecord TABLE = new DRFGAModifiedRecord();
foreach (ArrayFunc Row in ArrayFunc.QueryResult)
{
foreach (ArrayFunc Row2 in ArrayFunc.QueryResult1)
{
TABLE.RecordDocID = Row.FGACol1;
TABLE.DRNo = Row.FGACol2;
TABLE.DDNum = Row.FGACol3;
TABLE.LineNumber = Row.FGACol4;
TABLE.Itemnmbr = Row2.updItemCode;
TABLE.Itemdesc = Row2.updItemDesc;
TABLE.Pallet = Row2.updPallets;
TABLE.BagsNo = Row2.updBagsNo;
TABLE.TotalLoaded = Row2.updTotalKgs;
TABLE.PostStat = Row2.updPostStat;
TABLE.ProdCode = Row2.updProdcode;
TABLE.VariantCode = Row2.updVariantCode;
TABLE.DateModify = DateTime.Now.ToShortDateString();
TABLE.TimeModify = DateTime.Now.ToShortTimeString();
TABLE.UserModify = "Mik";//GlobalvarClass.LogUser;
TABLE.ReasonModify = GlobalvarClass.GetModReasOnDR;
TABLE.FileType = "New";
saveREC(TABLE);
gfunc.MsgBox("Saved", 1);
}
}
ArrayFunc.QueryResult.Clear();
ArrayFunc.QueryResult1.Clear();
GlobalvarClass.GetModReasOnDR = string.Empty;
}
catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); }
}
Is there another proper way to use this kind of code something like this to avoid duplicate? I know it duplicate because of two foreach statement
Just combine the two using linq. Remember to include using System.Linq; in your using clause.
var results = ArrayFunc.QueryResult.SelectMany(l1 => ArrayFunc.QueryResult1, (l1, l2) =>
new DRFGAModifiedRecord
{
RecordDocID = l1.FGACol1,
DRNo = l1.FGACol2,
DDNum = l1.FGACol3,
LineNumber = l1.FGACol4,
Itemnmbr = l2.updItemCode,
Itemdesc = l2.updItemDesc,
Pallet = l2.updPallets,
BagsNo = l2.updBagsNo,
TotalLoaded = l2.updTotalKgs,
PostStat = l2.updPostStat,
ProdCode = l2.updProdcode,
VariantCode = l2.updVariantCode,
DateModify = DateTime.Now.ToShortDateString(),
TimeModify = DateTime.Now.ToShortTimeString(),
UserModify = "Mik",//GlobalvarClass.LogUser
ReasonModify = GlobalvarClass.GetModReasOnDR,
FileType = "New"
}).ToList();
foreach (row in results)
{
saveREC(row);
gfunc.MsgBox("Saved", 1);
}
Alternatively you can do it with a query expression:
var result = (from l1 in ArrayFunc.QueryResult
from l2 in ArrayFunc.QueryResult1
select new DRFGAModifiedRecord { RecordDocID = l1.FGACol1 ... }).ToList();

Categories