How to print only the specified rows from the grid view - c#

Welcome
I have a sales screen with an invoice that is displayed in the grid view with the report of Extra Robert
I just want when I select some rows using the select box only the selected rows are printed on one page I tried this code but it prints each row in a separate report
I just want to print the selected rows on one page. Thank you
for (int i = 0; i <= DgvSale.Rows.Count - 1; i++)
{
if (Convert.ToBoolean(DgvSale.Rows[i].Cells[8].Value) == true)
{
tblRpt1 = db.readData("SELECT [Order_ID] as 'رقم الفاتورة',talb_ID as 'طلب',[Cust_Name] as 'اسم العميل',Products.Pro_Name as 'المنتج',Products.Group_ID as 'قسم',Products_Group.Group_Name as 'اسم القسم',[Sales_Detalis].[Qty] as 'الكمية',[Price] as 'السعر',[User_Name] as 'الكاشير',[Date] as 'التاريخ',[Unit] as 'الوحدة',[Sales_Detalis].Tax_Value as 'الضريبة',Price_Tax as 'السعر بعد الضريبة',[typetalab] as 'نوع الطلب',[priceservic] as 'خدمة',[shiftname] as 'شيفت',notes as 'ملاحظات',shiftnum as 'شيفت رقم',Print_Group.Print_Name,Print_Group.Name_Group FROM [dbo].[Sales_Detalis] , Products,Products_Group,Print_Group where Products.Pro_ID = Sales_Detalis.Pro_ID and Products.Pro_ID= " + row1.Cells[0].Value + " and Order_ID = " + id + " and Products.Group_ID = Products_Group.Group_ID and Print_Group.Name_Group=Products.Group_ID ORDER BY Order_ID ASC", "");
}
}
if (Properties.Settings.Default.SalePrintKind == "8CM")
{
devOrderSales2 rpt = new devOrderSales2() { DataSource = tblRpt1, DataMember = "OrderSales2" };
rpt.DataSource = tblRpt1;
rpt.Parameters["ID1"].Value = id;
rpt.PrinterName = Properties.Settings.Default.PrinterNameSteker;
rpt.xrTableCell8.Visible=true;
if (Properties.Settings.Default.saleprintauto == "0")
{
rpt.Print();
}
else if (Properties.Settings.Default.saleprintauto == "1")
{
rpt.ShowPreviewDialog();
}
}

I suggest to create the WHERE condition dynamically with the selected records:
string sql = #"SELECT [Order_ID] as 'رقم الفاتورة',talb_ID as 'طلب',[Cust_Name] as 'اسم العميل',Products.Pro_Name as 'المنتج',Products.Group_ID as 'قسم',Products_Group.Group_Name as 'اسم القسم',[Sales_Detalis].[Qty] as 'الكمية',[Price] as 'السعر',[User_Name] as 'الكاشير',[Date] as 'التاريخ',[Unit] as 'الوحدة',[Sales_Detalis].Tax_Value as 'الضريبة',Price_Tax as 'السعر بعد الضريبة',[typetalab] as 'نوع الطلب',[priceservic] as 'خدمة',[shiftname] as 'شيفت',notes as 'ملاحظات',shiftnum as 'شيفت رقم',Print_Group.Print_Name,Print_Group.Name_Group
FROM
[dbo].[Sales_Detalis]
INNER JOIN Products
ON Products.Pro_ID = Sales_Detalis.Pro_ID
INNER JOIN Products_Group
ON Products.Group_ID = Products_Group.Group_ID
INNER JOIN Print_Group
ON Print_Group.Name_Group=Products.Group_ID
WHERE
Products.Pro_ID IN ({0}) AND Order_ID = {1}
ORDER BY Order_ID ASC";
var productIds = new List<int>();
for (int i = 0; i <= DgvSale.Rows.Count - 1; i++) {
if (Convert.ToBoolean(DgvSale.Rows[i].Cells[8].Value) == true) {
productIds.Add(Convert.ToInt32(DgvSale.Rows[i].Cells[0].Value));
}
}
if (Properties.Settings.Default.SalePrintKind == "8CM" && productIds.Count > 0) {
string commandText = String.Format(sql, String.Join(", ", productIds), id);
tblRpt1 = db.readData(commandText, "");
var rpt = new devOrderSales2 {
DataSource = tblRpt1,
DataMember = "OrderSales2",
PrinterName = Properties.Settings.Default.PrinterNameSteker
};
rpt.xrTableCell8.Visible = true;
rpt.Parameters["ID1"].Value = id;
if (Properties.Settings.Default.saleprintauto == "0") {
rpt.Print();
} else if (Properties.Settings.Default.saleprintauto == "1") {
rpt.ShowPreviewDialog();
}
}
Also, you should use the modern JOIN syntax instead of the outdated join conditions in the WHERE clause.
Note that I have set up a SQL string with {0} and {1} as placeholders later being replaced with the String.Format method. I assumed the product ids to be of type int. The resulting WHERE conditions looks something like this:
WHERE
Products.Pro_ID IN (12, 30, 55, 68) AND Order_ID = 17
The C# verbatim strings introduced with #" allow you to include line breaks within the string and to make the SQL text more readable.
row1 always points to the same row. Get the row dynamically with DgvSale.Rows[i] instead, within the loop.

One way is to first collect all the relevant IDs from the rows, and only do 1 db query, eg:
var toprint_ids = new List<long>();
for (int i = 0; i <= DgvSale.Rows.Count - 1; i++)
{
if (Convert.ToBoolean(DgvSale.Rows[i].Cells[8].Value) == true)
{
var itm_id = Convert.ToInt64(row1.Cells[0].Value);
ids.Add(itm_id);
}
}
if (toprint_ids.Count == 0)
return;
tblRpt1 = db.readData("SELECT [Order_ID] as 'رقم الفاتورة',talb_ID as 'طلب',[Cust_Name] as 'اسم العميل',Products.Pro_Name as 'المنتج',Products.Group_ID as 'قسم',Products_Group.Group_Name as 'اسم القسم',[Sales_Detalis].[Qty] as 'الكمية',[Price] as 'السعر',[User_Name] as 'الكاشير',[Date] as 'التاريخ',[Unit] as 'الوحدة',[Sales_Detalis].Tax_Value as 'الضريبة',Price_Tax as 'السعر بعد الضريبة',[typetalab] as 'نوع الطلب',[priceservic] as 'خدمة',[shiftname] as 'شيفت',notes as 'ملاحظات',shiftnum as 'شيفت رقم',Print_Group.Print_Name,Print_Group.Name_Group FROM [dbo].[Sales_Detalis] , Products,Products_Group,Print_Group where Products.Pro_ID = Sales_Detalis.Pro_ID and Products.Pro_ID in (" + string.Join(",", toprint_ids) + ") and Order_ID = " + id + " and Products.Group_ID = Products_Group.Group_ID and Print_Group.Name_Group=Products.Group_ID ORDER BY Order_ID ASC", "");
if (Properties.Settings.Default.SalePrintKind == "8CM")
{
devOrderSales2 rpt = new devOrderSales2() { DataSource = tblRpt1, DataMember = "OrderSales2" };
rpt.DataSource = tblRpt1;
rpt.Parameters["ID1"].Value = id;
rpt.PrinterName = Properties.Settings.Default.PrinterNameSteker;
rpt.xrTableCell8.Visible=true;
if (Properties.Settings.Default.saleprintauto == "0")
{
rpt.Print();
}
else if (Properties.Settings.Default.saleprintauto == "1")
{
rpt.ShowPreviewDialog();
}
}
Please notice the change in the query as well: in (" + string.Join(",", toprint_ids) + ")
Also if you have non-numeric IDs for your rows (eg Guids), then you need to change the list to a List<string> and also change your query to like in ('" + string.Join("','", toprint_ids) + "')

Related

Exporting random rows to excel file based on int value

So I have my report printing out exactly what I want (almost). Now I just have to get one feature finished. I have a number that is generated and placed into a variable called percentage.
percentage equals the the rounded number of all the licenses in the database that allAttendeeLicenseNos pulls in multiplied by the number that is entered in by the user multiplied .01 to make it a percentage.
So my goal is to see all the attendees, and say okay this person only wants a percentage of them, but it doesn't matter which ones so I am going to grab random rows until the percentage number is there.
Again, please be patient as I am very new to C# and am learning.
var percentage = Math.Round(allAttendeeLicenseNos.Count() * Percentage * 0.01);
var allAttendeeData = _mii.LicenseeRecords.Where(r => allAttendeeLicenseNos.Contains(r.LicenseNumber)).Where(i => i.LicenseStatus.Equals(chosenLicenseStatus)).ToList();
var retval = _mapper.Map<List<DLILicense>, List<RandomAuditViewModel>>(allAttendeeData);
using (var exs = new ExcelPackage())
{
var worksheet = exs.Workbook.Worksheets.Add("RandomAuditReport");
var row = 1;
var col = 1;
var properties = typeof(RandomAuditViewModel).GetProperties();
foreach (var field in properties)
{
worksheet.Cells[row, col].Style.Font.Bold = true;
var displayName = field.GetCustomAttribute<DisplayAttribute>() != null ?
field.GetCustomAttribute<DisplayAttribute>().GetName() :
field.Name;
worksheet.SetValue(row, col, displayName);
col++;
}
col = 1;
row++;
retval.ForEach(i =>
{
var periodOrdinal = _ce.Events
.Where(e => e.Attendees.Select(a => a.LicenseNumber).Contains(i.LicenseNumber))
.Select(e => e.Course.CertificationPeriod)
.OrderBy(p => p.StartDate)
.ToList()
.IndexOf(thePeriod) + 1;
i.MetRequirements = determineIfCeMet(i.LicenseNumber, i.LicenseTypeCode, i.DateOfOriginalLicensure, periodOrdinal, thePeriod.Id, thePeriod.EndDate, thePeriod.Board);
foreach (var field in properties)
{
if (field.GetCustomAttribute<DataTypeAttribute>().DataType.Equals(DataType.Date))
{
var value = ((DateTime)field.GetValue(i));
worksheet.Cells[row, col].Style.Numberformat.Format = "MM/dd/yyyy";
worksheet.Cells[row, col].Formula = "=DATE(" + value.Year + "," + value.Month + "," + value.Day + ")";
}
else worksheet.SetValue(row, col, field.GetValue(i));
col++;
}
col = 1;
row++;
});
return exs.GetAsByteArray();
Something like below?
retval.ForEach(i =>
{
if(retval.IndexOf(i) == percentage)
break;
var periodOrdinal = _ce.Events
.Where(e => e.Attendees.Select(a => a.LicenseNumber).Contains(i.LicenseNumber))
.Select(e => e.Course.CertificationPeriod)
.OrderBy(p => p.StartDate)
.ToList()
.IndexOf(thePeriod) + 1;
i.MetRequirements = determineIfCeMet(i.LicenseNumber, i.LicenseTypeCode, i.DateOfOriginalLicensure, periodOrdinal, thePeriod.Id, thePeriod.EndDate, thePeriod.Board);
foreach (var field in properties)
{
if (field.GetCustomAttribute<DataTypeAttribute>().DataType.Equals(DataType.Date))
{
var value = ((DateTime)field.GetValue(i));
worksheet.Cells[row, col].Style.Numberformat.Format = "MM/dd/yyyy";
worksheet.Cells[row, col].Formula = "=DATE(" + value.Year + "," + value.Month + "," + value.Day + ")";
}
else worksheet.SetValue(row, col, field.GetValue(i));
col++;
}
col = 1;
row++;
})
Where you're using this
if(retval.IndexOf(i) == percentage)
break;
to determine if you've hit the percentage, then breaking out of the ForEach.

This row has been removed from a table and does not have any data

This row has been removed from a table and does not have any data. BeginEdit() will allow creation of new data in this row.
I have a method where I'm trying to delete all duplicate rows (using the date) and I'm getting the above exception with my code. I understand what the exception means but I don't understand what I'm doing wrong in my code to cause it. I have looked over it several times with no luck.
using (OldStockRatingsTableAdapter ratingsAdapter = new OldStockRatingsTableAdapter())
using (DataSet.OldStockRatingsDataTable ratingsTable = new DataSet.OldStockRatingsDataTable())
{
ratingsAdapter.ClearBeforeFill = true;
ratingsAdapter.Adapter.UpdateBatchSize = 500;
ratingsAdapter.FillByMarketSymbol(ratingsTable, market, symbol);
var masterQuery = from c in ratingsTable
where c.Symbol == symbol && c.Market == market
select c;
List<DataSet.OldStockRatingsRow> masterRows = masterQuery.ToList();
List<DataSet.OldStockRatingsRow> masterDistinctRows = masterQuery.DistinctBy(i => i.Date).ToList();
for (int i = 0; i < masterDistinctRows.Count; i++)
{
var dateQuery = from c in masterRows
where c.Date == masterDistinctRows.ElementAtOrDefault(i).Date
select c;
List<DataSet.OldStockRatingsRow> dateRow = dateQuery.ToList(); // getting the exception here
if (dateRow.Count > 1)
{
for (int j = 1; j < dateRow.Count; j++)
{
ratingsTable.RemoveOldStockRatingsRow(dateRow.ElementAtOrDefault(j));
Console.WriteLine("Stock rating deleted for " + symbol + " in the " + market + " market!");
}
}
}
// update everything here
DataSet.OldStockRatingsDataTable tempRatingsTable = new DataSet.OldStockRatingsDataTable();
tempRatingsTable = (DataSet.OldStockRatingsDataTable)ratingsTable.GetChanges();
if (tempRatingsTable != null)
{
ratingsAdapter.Adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
ratingsAdapter.Adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None;
ratingsAdapter.Adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
ratingsAdapter.Update(tempRatingsTable);
tempRatingsTable.Dispose();
Console.WriteLine("Stock rating calculations finished for " + symbol + " in the " + market + " market!");
}
}
I don't know about your code but if all that you are trying to do is delete duplicates then maby this code is of some use to you:
delete duplicate query
with x as (
select *, row_number() over(partition by <COLUMN>, checksum(<Columns to validate>) order by <COLUMN>) as rn
from <TABLE>
)
delete x where rn > 1
//it will validate multiple columns if more are given
Note: this code was not made by me, I'll link the origional post here. The code was posted by #dean.

How do I add multiple optional parameters to linq query

I Have to check and add the optional parameter in function but its taking lengthy code to go through IF-Else statement, If I choose switch statement then Cannot convert 'var' variable to string error keep coming up, How do I check and add optional parameters to linq query please help. Here is my code. (I will provide both the one with If statement and other one with switch statement which is throwing error)
Code 1 If-else statement:
public static void loadGrid(ref GridView gvMain, string cID, string desig = "All", string importancy = "All", string status = "All")
{
int _cId = Convert.ToInt32(cID);
List<clsclass> list = new List<clsclass>();
var db = new MyEntities();
if (_cId == 0 && desig == "All" && importancy == "All" && status == "All")
{
var query = from table in db.Members select table;
list.Clear();
foreach (var item in query)
{
clsclass ctl = new clsclass();
ctl.Id = Convert.ToInt32(item.LID);
ctl.Name = item.FirstName + " " + item.LastName;
ctl.Gender = item.Gender;
ctl.Age = Convert.ToInt32(item.Age);
ctl.Mobile = item.Mobile;
ctl.Workphone = item.WorkPhone;
ctl.Designation = item.Designation;
ctl.Importancy = item.Importancy;
list.Add(ctl);
}
}
else if (_cId != 0 && desig == "All" && importancy == "All" && status == "All")
{
var query = from table in db.Members where table.CID == _cId select table;
list.Clear();
foreach (var item in query)
{
clsclass ctl = new clsclass();
ctl.Id = Convert.ToInt32(item.LID);
ctl.Name = item.FirstName + " " + item.LastName;
ctl.Gender = item.Gender;
ctl.Age = Convert.ToInt32(item.Age);
ctl.Mobile = item.Mobile;
ctl.Workphone = item.WorkPhone;
ctl.Designation = item.Designation;
ctl.Importancy = item.Importancy;
list.Add(ctl);
}
}
//AND SO ON I HAVE TO CHECK THE OPTIONAL PARAMETERS......
//else if()
//{
//}
}
And In below code If I try to use switch statement to bind query based condition its throwing error:
Code 2:Switch statement:
public static void LoadGrid(ref GridView gvMain, string cID, string desig = "All", string importancy = "All", string status = "All")
{
int _cId = Convert.ToInt32(cID);
List<clsclass> list = new List<clsclass>();
var db = new MyEntities();
var query;
switch (query)
{
case _cId == 0 && desig == "All" && importancy == "All" && satus == "All":
query = from b in db.ConstituencyLeaders select b;
case _cId != 0 && desig == "All" && importancy == "All" && satus == "All":
query = from b in db.ConstituencyLeaders where b.ConstituencyID == _cId select b;
}
foreach (var item in query)
{
clsclass cl = new clsclass();
cl.LeaderId = item.LID;
//...remaining members add
list.Add(cl);
}
gvMain.DataSource = list;
gvMain.DataBind();
}
So basically I got two questions How to shorten the codes to capture the optional parameters if switch statement is better option then how would I achieve var query from Case:
any help much appreciated.
What you can do is.
var query = db.Members.AsQuerryable();
if(_cid != "")
{
query = query.where(table => table.CID == _cId);
}
Then use that in your statement
var result = from table in query where table.CID == _cId select table;
or we also used to do or statements.
var query= from table in query where (table.CID == _cId || _cId = "") select table;
so if the value is empty it just goes through or if there is a value it checks.

Index was out of range. Must be non-negative and less than the size of the collection in List<string>

I am using List object to store the user property.
My code is:
string department=string.Empty;
List<string> otherDepartments = new List<string>();
int no;
string result = string.Empty;
string queryText = string.Empty;
using (SPSite siteCollection = SPContext.Current.Site)
{
using(SPWeb site = siteCollection.OpenWeb())
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPUser spUser = site.CurrentUser;
SPServiceContext context = SPServiceContext.GetContext(siteCollection);
UserProfileManager upm = new UserProfileManager(context);
UserProfile profile = upm.GetUserProfile(spUser.LoginName);
department = profile["oiplbDepartment"].Value.ToString();
UserProfileValueCollection otherDept = profile["oiplbOtherDepartments"];
if (otherDept.Count != 0)
{
foreach (var prop in otherDept)
{
otherDepartments.Add(prop.ToString());
}
}
Label1.Text = department + " Ohter Departments " + otherDepartments;
});
SPList list = site.Lists["Events"];
SPListItemCollection itemColl;
SPQuery query = new SPQuery();
no = 1 + otherDepartments.Count;
for (int i = 1; i <= no; i++)
{
if (no == 1)
{
result = "<or> <Eq><FieldRef Name='oiplbDepartment' /><Value Type='TaxonomyFieldType'>"+department+"</Value></Eq>"+"</or>";
break;
}
else if (i == 2)
{
result = "<or> <Eq><FieldRef Name='oiplbDepartment' /><Value Type='TaxonomyFieldType'>" + department + "</Value></Eq>" +
"<Eq><FieldRef Name='oiplbDepartment' /><Value Type='TaxonomyFieldType'>" + otherDepartments[i-1] + "</Value></Eq>";
}
else if(i >= 3)
{
result = generateOr(result,otherDepartments[i-1]);
}
}
queryText = "<where>"+result +"</Where>";
query.Query = queryText;
itemColl = list.GetItems(query);
Grid.DataSource = itemColl.GetDataTable();
Grid.DataBind();
}
}
public static string generateOr(string temp, string value)
{
string r = "<or>" + temp + " <Eq><FieldRef Name='oiplbDepartment' /><Value Type='TaxonomyFieldType'>" + value + "</Value></Eq> </or>";
return r;
}
I am getting the above mentioned error when I run the program.
I am inserting a value if and only if the properties are available otherwise not.
But why am I getting the error?
Its because of
no = 1 + otherDepartments.Count;
change it to
no = otherDepartments.Count;
Even if you subtract 1 from i before you access the item in the list your for-loop loops until i == no. So you could also change i <= no to i < no
for (int i = 1; i < no; i++)

Looping and Assigning results to Textboxes

I have a linq query that pulls down some records. It could be 1 record, 2 records or 30 records. I have two textboxes I want the records to go into if there is only 1 record or only 2 records then it if its over that it puts it in a dropdownlist. This is what I have so far.
var getContacts = (from r in gServiceContext.CreateQuery("account")
join c in gServiceContext.CreateQuery("contact") on ((EntityReference) r["accountid"]).Id
equals c["accountid"]
where r["accountid"].Equals(ddlCustomer.SelectedValue)
select new
{
FirstName = !c.Contains("firstname") ? string.Empty : c["firstname"],
LastName = !c.Contains("lastname") ? string.Empty : c["lastname"],
});
foreach (var contact in getContacts)
{
if (getContacts.ToList().Count() == 1)
{
txtContact1Name.Text = contact.FirstName + " " + contact.LastName;
}
else if (getContacts.ToList().Count() == 2)
{
txtContact2Name.Text = contact.FirstName + " " + contact.LastName;
}
else if (getContacts.ToList().Count() > 2)
{
ddlMultipleContacts.DataSource = getContacts;
ddlMultipleContacts.DataTextField = "LastName";
ddlMultipleContacts.DataValueField = "LastName";
ddlMultipleContacts.DataBind();
}
}
But it puts the same record in textbox 1 and textbox two if there are two records. Am I doing something wrong?
Thanks!
But it puts the same record in textbox 1 and textbox two if there are two records. Am I doing something wrong?
Yes. Look at your code:
if (getContacts.ToList().Count() == 2)
You're calling that on each iteration - you're not using the count of how many contacts you've already used. I suspect you want:
// Let's only materialize the results *once* instead of once per iteration...
var contacts = getContacts().ToList();
switch (contacts.Count)
{
case 0: // What do you want to do here?
break;
case 1:
txtContact1Name.Text = FormatName(contacts[0]);
break;
case 2:
txtContact1Name.Text = FormatName(contacts[0]);
txtContact2Name.Text = FormatName(contacts[1]);
break;
default:
ddlMultipleContacts.DataSource = contacts;
ddlMultipleContacts.DataTextField = "LastName";
ddlMultipleContacts.DataValueField = "LastName";
ddlMultipleContacts.DataBind();
break;
}
var getContacts = (from r in gServiceContext.CreateQuery("account")
join c in gServiceContext.CreateQuery("contact") on ((EntityReference) r["accountid"]).Id
equals c["accountid"]
where r["accountid"].Equals(ddlCustomer.SelectedValue)
select new
{
FirstName = !c.Contains("firstname") ? string.Empty : c["firstname"],
LastName = !c.Contains("lastname") ? string.Empty : c["lastname"],
}).ToList();
if (getContacts.Count > 2)
{
ddlMultipleContacts.DataSource = getContacts;
ddlMultipleContacts.DataTextField = "LastName";
ddlMultipleContacts.DataValueField = "LastName";
ddlMultipleContacts.DataBind();
}
else if (getContacts.Count == 1)
{
txtContact1Name.Text = contact.FirstName + " " + contact.LastName;
}
else if (getContacts.Count == 2)
{
txtContact1Name.Text = contact[0].FirstName + " " + contact[0].LastName;
txtContact2Name.Text = contact[1].FirstName + " " + contact[1].LastName;
}

Categories