I'm still learning in programming
I'm trying to get customer data in list. So I can get the value from the index, but it only can get the first customer. the index won't increment, I'm still confusing, I have already move the variable for increment the index won't work, maybe my logic isn't right. here's the code, tell me where is not right..?? thank you for you help and explanation
public void getJamVSpot()
{
var listJamAwal = new List<String>();
var listJamAkhir = new List<String>();
var listNota = new List<int>();
DateTime tglSewa = dtp_tglSewa.Value.Date;
int r = 0;
String ja = String.Empty;
String jb = String.Empty;
int n = 0;
int indexUp = 0;
if (dtp_tglSewa.Value.Date == jl.getTglJadwalVspot(tglSewa, lap) && rdb_Lapangan_VSpot.Checked == true || rdb_rumputSintetis.Checked == true)
{
IEnumerator<String> jAwal = jl.getJamAwalbyDate(tglSewa, lap);
while (jAwal.MoveNext())
{
listJamAwal.Add(jAwal.Current);
}
IEnumerator<String> jAkhir = jl.getJamAkhirbyDate(tglSewa, lap);
while (jAkhir.MoveNext())
{
listJamAkhir.Add(jAkhir.Current);
}
IEnumerator<int> nota = jl.getNota(tglSewa, lap);
while (nota.MoveNext())
{
listNota.Add(nota.Current);
}
ja = listJamAwal[indexUp];
jb = listJamAkhir[indexUp];
n = listNota[indexUp];
int count = jl.countNota(n);
String penyewa = jl.getNamaPenyewa(n);
String no_kontak = jl.getNomorKontak(n);
String status = jl.getStatusSewa(n);
for (int i = 1; i <= count; i++)
{
foreach (DataGridViewRow row in dgv_Jadwal_Sewa.Rows)
if (row.Cells[0].Value.ToString().Equals(ja))
{
r = row.Index;
row.Cells[2].Value = penyewa;
row.Cells[3].Value = no_kontak;
row.Cells[4].Value = status;
if (ja != jb)
{
ja = jl.getJamAkhirbyJamAwal(ja);
row.Cells[2].Value = penyewa;
row.Cells[3].Value = no_kontak;
row.Cells[4].Value = status;
//dgv_Jadwal_Sewa.Rows[r].Selected = true;
}
break;
}
}
} indexUp++;
}
When you increment the indexUp variable you aren't using it anymore.
In your code you are just recovering the first item (0), doing some stuff with this value (in the loops) and exits.
For example, you can wrap your stuff with this loop:
for (int indexUp = 0; indexUp < listJamAwal.Count; indexUp++)
{
ja = listJamAwal[indexUp];
jb = listJamAkhir[indexUp];
n = listNota[indexUp];
int count = jl.countNota(n);
String penyewa = jl.getNamaPenyewa(n);
String no_kontak = jl.getNomorKontak(n);
String status = jl.getStatusSewa(n);
for (int i = 1; i <= count; i++)
{
foreach (DataGridViewRow row in dgv_Jadwal_Sewa.Rows)
{
if (row.Cells[0].Value.ToString().Equals(ja))
{
r = row.Index;
row.Cells[2].Value = penyewa;
row.Cells[3].Value = no_kontak;
row.Cells[4].Value = status;
if (ja != jb)
{
ja = jl.getJamAkhirbyJamAwal(ja);
row.Cells[2].Value = penyewa;
row.Cells[3].Value = no_kontak;
row.Cells[4].Value = status;
//dgv_Jadwal_Sewa.Rows[r].Selected = true;
}
break;
}
}
}
}
There are two problems with how you access the items:
You assign the variables outside the loop. That will get the values that the index points to at that moment, and changing the index variable later doesn't change what's assigned to the variables. You have to assign the variables inside the loop, except the count variable of course which you need before the loop starts.
You are incrementing the indexUp variable after the loop, when you have no use for it any more. You have to put that inside the loop so that it can be used in the next iteration to read new values into the variables.
I dont see any point of using first loop with "i" and then second with foreach. Its totally wrong - you are doing the same thing "count" times!
You also need to change penyewa, no_kontak, status because you are using same values inside loop
And in addition, I have never seen so confusing and unclear variable naming, you should change it if you want some else to use it :D
Related
How do you make the list receives more than 1 value based on the quantity of the SelectedList.Count.
Code:
for (int i = 0; i < SelectedList.Count; i++)
{
lastSeriesNo++;
string assetcodegen = string.Format("{0}-{1}-{2}", List[i].AssetCategoryID, CurrentApplication.Now.Year, lastSeriesNo.ToString().PadLeft(5, '0'));
AssetCodeOfficial[i] = assetcodegen;
var list = (from x in ctx.DataContext.AssetRegistryEntities
where x.AssetCode == SelectedList[i].AssetCode
select x
).AsEnumerable();
foreach (var asset in list)
{
asset.SeriesNumber = (short)lastSeriesNo;
asset.Status = 'A';
asset.IsTemp = false;
asset.UpdatedBy = CurrentApplication.CurrentUserId;
asset.UpdatedDate = asset.AssetCreatedDate = CurrentApplication.Now;
AssetCodetemp[i] = asset.AssetCode;
depreciationInMonths = asset.DepnInMonths;
ctx.DataContext.SubmitChanges();
}
}
Thank you all guys for the help, I manage to fix my problem. It already saves the data to the database as bulk not 1 by 1 saving.
So I use lambda expression for my list and use the .addRange to add item to the list.
list.AddRange(ctx.DataContext.AssetRegistryEntities.Where(x=>x.AssetCode.Trim() == SelectedList[i].AssetCode.Trim()));
Code:
List<NXpert.FixedAsset.DataAccess.AssetRegistryEntity> list = new List<NXpert.FixedAsset.DataAccess.AssetRegistryEntity>();
for (int i = 0; i < SelectedList.Count; i++)
{
lastSeriesNo++;
string assetcodegen = string.Format("{0}-{1}-{2}", List[i].AssetCategoryID, CurrentApplication.Now.Year, lastSeriesNo.ToString().PadLeft(5, '0'));
AssetCodeOfficial[i] = assetcodegen;
list.AddRange(ctx.DataContext.AssetRegistryEntities.Where(x=>x.AssetCode.Trim() == SelectedList[i].AssetCode.Trim()));
AssetCodetemp[i] = list[i].AssetCode;
}
foreach (var asset in list)
{
asset.SeriesNumber = (short)lastSeriesNo;
asset.Status = 'A';
asset.IsTemp = false;
asset.UpdatedBy = CurrentApplication.CurrentUserId;
asset.UpdatedDate = asset.AssetCreatedDate = CurrentApplication.Now;
depreciationInMonths = asset.DepnInMonths;
}
ctx.DataContext.SubmitChanges();
When we create a DataView with sort on multiple columns, we are forced to specify values of all the columns when using FindRows.
Example, if I have:
dv1 = new DataView(tbl1, null, "Col1, Col2, Col3", DataViewRowState.CurrentRows);
I am forced to specify values for all 3 columns when using FindRows.
It is not possible to retrieve all rows for a particular value of Col1 and "any" value for Col2 and Col3.
This is possible in a SortedList where I can have nested SortedList. So, the top level SortedList will have key as Col1, and value as another SortedList. The 2nd level SortedList will have key as Col2, and value as another SortedList. Finally, the 3rd level SortedList will have key as Col3, and the references to the DataRows.
Using such a SortedList, it is possible to write methods, like:
public DataRowView[] FindAny(object[] keys)
where if the keys array contains only 1 key, the code can find the 2nd level SortedList from the 1st level SortedList for the key, and then loop through the 2nd and 3rd level SortedList and return all rows, as they belong to 1st key.
My question is whether anyone has already written such a SortedList class which can take dynamic number of keys, and work with any DataTable / DataRow.
Note:
1. This question has nothing to do with presentation layer. I am looking for a helper class for data processing, say for analysing huge volume of data in multiple excel sheets.
2. I am not looking for a LINQ based solution currently. I will migrate to LINQ in future.
Thanks.
I managed to write my own generic class, which implements a hierarchial view of the data. Improvements in this are welcome.
public class HDataView
{
private SortedList mapDataRows;
int numMapLevels;
public HDataView(DataTable tbl, string[] colNames)
{
object colVal = null;
string colName = "";
SortedList currLvlMap = null, nextLvlMap = null;
DataRow dr1 = null;
ArrayList arlLastLvlData;
mapDataRows = new SortedList();
numMapLevels = colNames.Length;
for (int i = 0; i < tbl.Rows.Count; i++)
{
dr1 = tbl.Rows[i];
currLvlMap = mapDataRows;
for (int j = 0; j < colNames.Length; j++)
{
colName = colNames[j];
colVal = dr1[colName];
if (j == colNames.Length - 1)
{
arlLastLvlData = (ArrayList)currLvlMap[colVal];
if (arlLastLvlData == null)
{
arlLastLvlData = new ArrayList();
currLvlMap[colVal] = arlLastLvlData;
}
arlLastLvlData.Add(dr1);
}
else
{
nextLvlMap = (SortedList)currLvlMap[colVal];
if (nextLvlMap == null)
{
nextLvlMap = new SortedList();
currLvlMap[colVal] = nextLvlMap;
}
//For the next column, the current nextLvlMap will become the prevLvlMap
currLvlMap = nextLvlMap;
}
}
}
}
public ArrayList FindAnyRows(object[] keys)
{
object keyVal = "";
ArrayList arlDataRows = null, arlCurrRows = null;
SortedList startLvlMap = null, currLvlMap = null, nextLvlMap = null;
int mapLevel = 1, startLevel = 0;
currLvlMap = mapDataRows;
mapLevel = 1;
for (int i = 0; i < keys.Length; i++)
{
keyVal = keys[i];
if (currLvlMap == null)
{
break;
}
if (i == numMapLevels - 1)
{
arlDataRows = (ArrayList)currLvlMap[keyVal];
}
else
{
nextLvlMap = (SortedList)currLvlMap[keyVal];
currLvlMap = nextLvlMap;
mapLevel++;
}
}
if (arlDataRows == null)
{
arlDataRows = new ArrayList();
}
if (keys.Length > 0 && keys.Length < numMapLevels)
{
if (currLvlMap != null)
{
startLvlMap = currLvlMap;
startLevel = mapLevel;
if (mapLevel == numMapLevels)
{
for (int j = 0; j < startLvlMap.Count; j++)
{
arlCurrRows = (ArrayList)startLvlMap.GetByIndex(j);
if (arlCurrRows != null)
{
arlDataRows.AddRange(arlCurrRows);
}
}
}
else
{
for (int i = 0; i < startLvlMap.Count; i++)
{
mapLevel = startLevel;
currLvlMap = startLvlMap;
//travel full depth of this map, for each element of this map
for (; mapLevel <= numMapLevels; mapLevel++)
{
if (mapLevel == numMapLevels)
{
for (int j = 0; j < currLvlMap.Count; j++)
{
arlCurrRows = (ArrayList)currLvlMap.GetByIndex(j);
if (arlCurrRows != null)
{
arlDataRows.AddRange(arlCurrRows);
}
}
}
else
{
//Next level of current element of the starting map
nextLvlMap = (SortedList)currLvlMap.GetByIndex(i);
currLvlMap = nextLvlMap;
}
}
}
}
}
}
return arlDataRows;
}
}
I've been searching this page and other pages in this matter. I know it's not possible to get the data inside the while loop with direct assigning of variables, so I've tried to put it to label before and it works but only to the first value of the finalcred and finaldeb. It will not reset to fetch another value, so my real question is; Is there any other way to get the value inside the while loop and use it outside?
I have tried to declare it outside while and assign default value and the result will always be the default. It will not change.
r = t.NewRow();
//somecode..all good here
while (counterdate <= monthval)
{
//allgood in this part
totalcred = 0;
totaldeb = 0;
balance = 0;
crednum = 0;
debnum = 0;
if (readgetcode1.HasRows)
{
while (readgetcode1.Read())
{
readgetcred.Read();
readgetdeb.Read();
if (readgetdeb.HasRows)
{
debnum = Convert.ToDecimal(readgetdeb.GetValue(0));
}
else
{
debnum = 0;
}
if (readgetcred.HasRows)
{
crednum = Convert.ToDecimal(readgetcred.GetValue(0));
}
else
{
crednum = 0;
}
totalcred += crednum;
totaldeb += debnum;
if (strType == "Debit")
{
balance = totaldeb - totalcred;
}
else
{
balance = totalcred - totaldeb;
}
allbal += balance;
}
}
else
{
allbal = 0;
}
if (readprevCred.HasRows)
{
prevBalNum = Convert.ToDecimal(readprevBal.GetValue(0));
}
else
{
prevBalNum = 0;
}
if (strType == "Debit")
{
finaldeb = prevBalNum + allbal;
finalcred = 0;
}
else
{
finalcred = prevBalNum + allbal;
finaldeb = 0;
}
counterdate++;
}//while counterdate looping
r["accntCode"] = codevalue;
r["accntName"] = accntnameval;
r["DebitAmount"] = finaldeb;//this is the problem
r["CreditAmount"] = finalcred;;//this is the problem
t.Rows.Add(r);
//while readcodecheck in counter for code
I want to assign a data to an int volunteerEducation if I Checked radio button to save it to the database!
int volunteerEducation;
switch (volunteerEducation)
case radioButton9.Checked:
volunteerEducation= 9;
break;
case radioButton10.Checked:
volunteerEducation = 10;
break;
try this...
foreach(Control c in this.Controls)
{
if(c is RadioButton)
{
RadioButton rbtn = (RadioButton)c;
// now here you can use if else statements or Switch Statement
}
}
switch allows you to check for one of several values on a single variable. if statements allow arbitrary conditions, which can check a single variable or many. Hence, switch is unsuited for what you are trying to do.
There are a few obvious options:
Use a series of if ... else if statements
Use some fancier construct such as a lookup dictionary mapping to methods (Dictionary<RadioButton,Func<>> might be a good place to start), though if you are unfamiliar with such constructs as switch I'd strongly recommend against that (it's the old "you have to learn to walk before you start to run")
Iterate over the radio buttons and do your magic inside a loop
Such a loop would look like:
foreach (Control c in this.Controls)
{
RadioButton rbtn = c as RadioButton;
if(rbtn != null)
{
// ... your code to work with 'rbtn' goes here ...
if (rbtn.Checked)
{
// ...
}
}
}
Using as rather than is followed by an explicit cast is idiomatic, and also saves you a cast; null checking is almost certainly faster, and certainly not slower, than casting. The as operator gives you null if the given value cannot be cast to the given type. In the case where the value of the variable you are working can be changed from another thread (not likely in this case, but possible in other cases), it also saves you the headache of a nigh-impossible-to-reproduce bug when something changes the value of the variable out under your feet.
A set of if statements to do the same thing would be along the lines of
if (radioButton9.Checked)
{
// do something
}
else if (radioButton10.Checked)
{
// do something
}
Using else if mimics the behavior of a switch ... case ... break construct. If they are independent, simply omit the else. (Then, I'd suggest adding a blank line between the end of the if statement-block and the next if statement, for readability.)
I found the Answer and it's not really different from thus answers.
the Point is to declare int. e.g int volunteerEducation = 0; then you have to use if ... else if.
private void updateButton_Click(object sender, EventArgs e)
{
try
{
string volunteerID = updtIDTextBox.Text;
string volunteerName = updtNameTextBox.Text;
string volunteerZone = updtZoneTextBox.Text;
string volunteerStreet = updtStreetTextBox.Text;
int volunteerSex = updtMaleRadioButton.Checked ? 0 : 1;
DateTime volunteerBirthday = updtBirthdayDateTimePicker.Value;
if (updtHomePhoneTextBox.Text == "")
updtHomePhoneTextBox.Text = "0";
int volunteerHomePhone = int.Parse(updtHomePhoneTextBox.Text);
if (updtWorkPhoneTextBox.Text == "")
updtWorkPhoneTextBox.Text = "0";
int volunteerWorkPhone = int.Parse(updtWorkPhoneTextBox.Text);
if (updtMobile1TextBox.Text == "")
updtMobile1TextBox.Text = "0";
int volunteerMobile1 = int.Parse(updtMobile1TextBox.Text);
if (updtMobile2TextBox.Text == "")
updtMobile2TextBox.Text = "0";
int volunteerMobile2 = int.Parse(updtMobile2TextBox.Text);
string volunteerEmail = updtEmailTextBox.Text;
string volunteerJob = updtJobTextBox.Text;
string volunteerAffiliation = updtAffiliationTextBox.Text;
//The solution start from here
int volunteerEducation = 0;
if (radioButton10.Checked)
volunteerEducation = 1;
else if (radioButton11.Checked)
volunteerEducation = 2;
else if (radioButton12.Checked)
volunteerEducation = 3;
else if (radioButton14.Checked)
volunteerEducation = 5;
else if (radioButton15.Checked)
volunteerEducation = 6;
else if (radioButton16.Checked)
volunteerEducation = 7;
else if (radioButton17.Checked)
volunteerEducation = 8;
else if (radioButton18.Checked)
volunteerEducation = 9;
//end solution
string volunteerEducationPlace = addEducationPlaceTextBox.Text;
string volunteerEducationDepartmen = addEducationDepartmentTextBox.Text;
//same above
int volunteerInteresting = 0;
if (updtIntrstMdcnRadioButton.Checked)
volunteerInteresting = 1;
else if (updtIntrstSosclRadioButton.Checked)
volunteerInteresting = 2;
else if (updtIntrstLrnRadioButton.Checked)
volunteerInteresting = 3;
else if (updtIntrstTrnRadioButton.Checked)
volunteerInteresting = 4;
//end
string volunteerNotes = addNotesTextBox.Text;
int x = dataGridViewX1.SelectedRows[0].Index;
UpdateVolunteer(volunteerID, volunteerName, volunteerZone, volunteerStreet, volunteerSex, volunteerBirthday, volunteerHomePhone, volunteerWorkPhone, volunteerMobile1, volunteerMobile2, volunteerEmail, volunteerJob, volunteerAffiliation, volunteerEducation, volunteerEducationPlace, volunteerEducationDepartmen, volunteerInteresting, volunteerNotes);
showVolunteers(x);
updtIDTextBox.Text = "";
updtNameTextBox.Text = "";
updtZoneTextBox.Text = "";
updtStreetTextBox.Text = "";
updtBirthdayDateTimePicker.Value = DateTime.Now;
updtHomePhoneTextBox.Text = "";
updtWorkPhoneTextBox.Text = "";
updtMobile1TextBox.Text = "";
updtMobile2TextBox.Text = "";
updtEmailTextBox.Text = "";
updtJobTextBox.Text = "";
updtAffiliationTextBox.Text = "";
updtEducationPlaceTextBox.Text = "";
updtEducationDepartmentTextBox.Text = "";
updtNotesTextBox.Text = "";
}
catch (SqlException sql)
{
MessageBoxEx.Show(sql.Message);
}
}
I have a collection that I am inserting into the Dictionary and there are values that have already been entered into the KVPs. Say I already have a key of "4000" and the value comes up again, what happens to the value? Does it add the value of the key instance to the value that already exists for that key? Does it over write the value?
If it over writes, how can I add the values as they iterate through the collection of values?
public class AccountBalance
{
public decimal balance { get; set; }
public bool balancesheetact { get; set; }
public AccountBalance()
{
balance = 0;
balancesheetact = false;
}
}
Dictionary<string, List<AccountBalance>> balances = new Dictionary<string, List<AccountBalance>>();
var jentries = from je in gl.JEHeaders
where je.ped_int_id >= beginperiod && je.ped_int_id <= endperiod
orderby je.ped_int_id
select je;
bool isBalanceSheet;
foreach (JEHeader header in jentries)
{
foreach (JEDetail entry in header.JEDetails)
{
string subAccount = entry.ChartOfAccounts.acc_ext_id.Trim();
string key = subAccount.Remove(0, 4);
if (entry.ChartOfAccounts.acc_ty >= 15320 && entry.ChartOfAccounts.acc_ty <= 15322)
isBalanceSheet = true;
else
isBalanceSheet = false;
AccountBalance value = null;
if (!balances.ContainsKey(key))
{
List<AccountBalance> account_balances = new List<AccountBalance>();
// for (int i = 0; i < 12; ++i)
for (int i = 0; i < 14; ++i)
account_balances.Add(new AccountBalance());
balances.Add(key, account_balances);
}
// value = balances[key][header.ped_int_id % beginperiod];
value = balances[key][(header.ped_int_id % beginperiod) + 1];
/// NEW
if (header.ped_int_id == 637)
value = balances[key][0];
/// end NEW
if (entry.jnl_pst_deb_at != null)
value.balance += entry.jnl_pst_deb_at.HasValue ? entry.jnl_pst_deb_at.Value : 0;
if (entry.jnl_pst_crd_at != null)
value.balance -= entry.jnl_pst_crd_at.HasValue ? entry.jnl_pst_crd_at.Value : 0;
if (isBalanceSheet == true)
value.balancesheetact = true;
else
value.balancesheetact = false;
}
}
balances = balances.OrderBy(kvp => kvp.Key).ToDictionary(xyz => xyz.Key, xyz => xyz.Value);
int row = 0;
decimal ytdbalance;
foreach (KeyValuePair<string, List<AccountBalance>> account in balances)
{
row++;
//string subAccount = account.Key.Remove(0, 4);
workbook.AddCell(row, 0, account.Key);
ytdbalance = 0;
bool BS = account.Value[0].balancesheetact;
for (int i = 1; i < 13; ++i)
{
ytdbalance = ytdbalance + account.Value[i].balance;
if (BS == true)
workbook.AddCell(row, i + 1, ytdbalance);
else
workbook.AddCell(row, i + 1, account.Value[i].balance);
}
}
Dictionaries are 1 to 1 maps, if you need a 1 to many map, you can create a Lookup.
Adding a duplicate to a dictionary will result in an ArgumentException.
It does overwrite. If you want to add the value to the existing one, I believe you're looking for:
if (dict.ContainsKey(key)) {
dict[key] += newVal;
} else {
dict[key] = newVal;
}
// or
int currentVal;
dict.TryGetValue(key, out currentVal);
dict[key] = currentVal + newVal;
You have to check to see if it exists first, then if it does, add the values and re-insert to the dictionary. If it doesn't exist, you can set it like normal.
Watch out for thread safety here - if your dictionary is accessed through multiple threads, this code could potentially get your dictionary out of whack.
If you want to just add values as you go along then instead of say Dictionary<String,String> you want Dictionary<String,List<String>> and instead of just calling add something like
if (!myDict.ContainsKey(someKey))
{
myDict.Add(someKey,new List<String>());
}
myDict[somekey].Add(somevalue);
one way to do it anyway.