rwheeler23
asked on
VS C# Record Counter
In this little snippet of code I am trying to display a record counter as records are read. I am trying to use lblCounter.Text = rc.ToString();
However, all this does is give me a blank screen and the only record counter that appears is the final record counter after all records have been read.
How do I update this code to show a record count as each record is read?
foreach (DataRow dr_cmploop in DataDataTable.Rows)
{
if ( rc % 50 == 0) /* Allow no more than 50 transactions per batch. For each 50 transactions create a new batch */
{
bcounter++; /* Increment the batch counter for each 50 transactions */
/* Create the batch name */
BACHNUMB = bprefix + string.Format("{0:d4}", DateTime.Today.Year) + "-" + string.Format("{0:d2}", DateTime.Today.Month) + "-" + string.Format("{0:d3}",bco unter);
/* Create the batch header */
CreateBatchHeader();
}
rc++; /* Increment the record counter for each transaction to be imported */
lblCounter.Text = rc.ToString();
dr = dr_cmploop;
//tw.WriteLine("{0};{1};{2 };{3};{4}; {5};{6};{7 };{8};{9}" , dr["YYYY"], dr["MM"], dr["Company_Code"], dr["Inter_Company_Code"], dr["Master_Account"], dr["Account"], dr["Sign"], dr["Balance"], dr["Master_Account_Descrip tion"], dr["Account_Description"]) ;
}
However, all this does is give me a blank screen and the only record counter that appears is the final record counter after all records have been read.
How do I update this code to show a record count as each record is read?
foreach (DataRow dr_cmploop in DataDataTable.Rows)
{
if ( rc % 50 == 0) /* Allow no more than 50 transactions per batch. For each 50 transactions create a new batch */
{
bcounter++; /* Increment the batch counter for each 50 transactions */
/* Create the batch name */
BACHNUMB = bprefix + string.Format("{0:d4}", DateTime.Today.Year) + "-" + string.Format("{0:d2}", DateTime.Today.Month) + "-" + string.Format("{0:d3}",bco
/* Create the batch header */
CreateBatchHeader();
}
rc++; /* Increment the record counter for each transaction to be imported */
lblCounter.Text = rc.ToString();
dr = dr_cmploop;
//tw.WriteLine("{0};{1};{2
}
Try putting Application.DoEvents() under the if statement and see if that helps.
That would update after every 50 records. Put directly under the for loop if you want every record. Of course that will slow things down.
This is a copy from a previous question by you about this:
you mean something like the following where lbl is a label on your form.
int i = 1;
foreach(record in rs)
{
i++;
lbl.Text = i.ToString();
DoEvents(); //allow message loop to run, else lbl never appears to update
DoSomething();
}
you mean something like the following where lbl is a label on your form.
int i = 1;
foreach(record in rs)
{
i++;
lbl.Text = i.ToString();
DoEvents(); //allow message loop to run, else lbl never appears to update
DoSomething();
}
ASKER
I added the Application.DoEvents() command right after the if statement. I only see the record count once all records have been processed.
foreach (DataRow dr_cmploop in DataDataTable.Rows)
{
if ( rc % 50 == 0) /* Allow no more than 50 transactions per batch. For each 50 transactions create a new batch */
{
bcounter++; /* Increment the batch counter for each 50 transactions */
/* Create the batch name */
BACHNUMB = bprefix + string.Format("{0:d4}", DateTime.Today.Year) + "-" + string.Format("{0:d2}", DateTime.Today.Month) + "-" + string.Format("{0:d3}",bco unter);
/* Create the batch header */
CreateBatchHeader();
}
Application.DoEvents();
rc++; /* Increment the record counter for each transaction to be imported */
lblCounter.Text = rc.ToString();
dr = dr_cmploop;
/* Get the next AP voucher number */
SqlCommand cmd = new SqlCommand();
Object returnValue;
cmd.CommandText = "SELECT NTVCHNUM FROM PM40100";
cmd.CommandType = CommandType.Text;
cmd.Connection = DataConnection;
returnValue = cmd.ExecuteScalar();
NTVCHNUM = returnValue.ToString();
/* Increment the next AP voucher number */
IncrementNextAPVoucher();
}
foreach (DataRow dr_cmploop in DataDataTable.Rows)
{
if ( rc % 50 == 0) /* Allow no more than 50 transactions per batch. For each 50 transactions create a new batch */
{
bcounter++; /* Increment the batch counter for each 50 transactions */
/* Create the batch name */
BACHNUMB = bprefix + string.Format("{0:d4}", DateTime.Today.Year) + "-" + string.Format("{0:d2}", DateTime.Today.Month) + "-" + string.Format("{0:d3}",bco
/* Create the batch header */
CreateBatchHeader();
}
Application.DoEvents();
rc++; /* Increment the record counter for each transaction to be imported */
lblCounter.Text = rc.ToString();
dr = dr_cmploop;
/* Get the next AP voucher number */
SqlCommand cmd = new SqlCommand();
Object returnValue;
cmd.CommandText = "SELECT NTVCHNUM FROM PM40100";
cmd.CommandType = CommandType.Text;
cmd.Connection = DataConnection;
returnValue = cmd.ExecuteScalar();
NTVCHNUM = returnValue.ToString();
/* Increment the next AP voucher number */
IncrementNextAPVoucher();
}
//Application.DoEvents();
rc++; /* Increment the record counter for each transaction to be imported */
lblCounter.Text = rc.ToString();
Application.DoEvents();
But I don't see why your code didn't update as processing happened.
rc++; /* Increment the record counter for each transaction to be imported */
lblCounter.Text = rc.ToString();
Application.DoEvents();
But I don't see why your code didn't update as processing happened.
I've made a new project, one form with a button and a label.
Try it both with and without the line Application.DoEvents() - with the line you should see the label change (rapidly), without it is unchanging until it shows 99
private void button1_Click(object sender, EventArgs e)
{
for(int i = 0; i < 100; i++)
{
foo();
label1.Text = i.ToString();
Application.DoEvents();
}
}
private void foo()
{
for(int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
for (int k = 0; k < 100; k++)
{
int m = i * 100 * 100 + j * 100 + k;
}
}
}
}
Try it both with and without the line Application.DoEvents() - with the line you should see the label change (rapidly), without it is unchanging until it shows 99
ASKER
OK, i need to find the difference in the code. I just placed a test button and pasted your code in there. I click the Test button and there is the counter. One difference I see is that using your example the button click directly has the loop. In my code, the button click opens a window and then there is a call to a function that has the loop in it. So the iteration happens another level deep. Let me play with this and see if I can arrange things differently.
>>In my code, the button click opens a window...
thinks.... Modal window ? With the label on the parent (disabled) form because it has opened a modal child window ?
thinks.... Modal window ? With the label on the parent (disabled) form because it has opened a modal child window ?
ASKER
Please excuse my ignorance but this is a concept I have been fighting with ever since I started coding in VS C#. So I have a parent window that has a button that opens a child window. From my understanding the modal child form now has control until the user exits it. So is there some way I reference the label in the child form? The child window is opened and displayed on the screen. Or is there some way to get the Application.DoEvent() to reference the child window?
Before we get all confused where is the label, on which form ?
Also is the 'new' form a modal form or modeless (.Show or .ShowDialog) ?
Also is the 'new' form a modal form or modeless (.Show or .ShowDialog) ?
ASKER
Here is how the form is called.
private void btnIntegrate_Click(object sender, EventArgs e)
{
if (IntegratePayables == null || IntegratePayables.Created == false)
{
IntegratePayables = new frmIntegratePayables();
}
IntegratePayables.Show();
IntegratePayables.Activate ();
IntegratePayables.Focus();
}
On this form(child form) there is a label called label1. It is this label I am trying to get to display the record count. Right now it only shows the record count when the loop is completed not while it is running.
private void btnIntegrate_Click(object sender, EventArgs e)
{
if (IntegratePayables == null || IntegratePayables.Created == false)
{
IntegratePayables = new frmIntegratePayables();
}
IntegratePayables.Show();
IntegratePayables.Activate
IntegratePayables.Focus();
}
On this form(child form) there is a label called label1. It is this label I am trying to get to display the record count. Right now it only shows the record count when the loop is completed not while it is running.
That is modeless - so both forms should be enabled.
As the label is also on the form running the code (and active) then that should be processing messages without problems.
As the label is also on the form running the code (and active) then that should be processing messages without problems.
ASKER
Is there some property of the form that may be controlling this? I noticed that when I click the integrate button, a blank form appears and it is only when the loop is done that I see the record count. Should I move the loop into the main body of the code as opposed to putting it down in a function?
>>I noticed that when I click the integrate button, a blank form appears
Are you putting the record processing code inside the FormLoad event? If yes then that might be the problem
Are you putting the record processing code inside the FormLoad event? If yes then that might be the problem
ASKER
Here is the code in the form. There is nothing in the form load event.
public frmIntegratePayables()
{
InitializeComponent();
/* Open the connection */
DataConnection = GetConnection();
/* Parse the import records and insert the payables transactions into batches */
IntegrateTransactions();
}
========================== ========== ========== ========== ========== =
Here is the IntegrateTransaction code
private void IntegrateTransactions()
{
/* Set the batch and record counters to 1 */
bcounter = 0;
rc = 0;
/* Define dataset for Transaction Types */
DataDataSet = new System.Data.DataSet();
DataDataSet.CaseSensitive = false;
DataDataCommand = new System.Data.SqlClient.SqlC ommand();
DataDataCommand.Connection = DataConnection;
DataDataCommand.CommandTex t = "select distinct Number,case when DocumentType = 'Invoice' then 1 else 4 end as DocType," +
"coalesce(Reference,'') as Reference,PurchaseDate,Pos tDate,coal esce(CRI,' ') as PONUMBER,VENDORID, Purchases " +
"from PEF_VendorBatchLoadTransac tion where wasimported = 0 and VendorFound = 1 and GLAccountMatched=1";
DataDataAdapter = new System.Data.SqlClient.SqlD ataAdapter ();
DataDataAdapter.SelectComm and = DataDataCommand;
DataDataAdapter.Fill(DataD ataSet);
DataDataTable = DataDataSet.Tables[0];
foreach (DataRow dr_cmploop in DataDataTable.Rows)
{
if ( rc % 50 == 0) /* Allow no more than 50 transactions per batch. For each 50 transactions create a new batch */
{
bcounter++; /* Increment the batch counter for each 50 transactions */
/* Create the batch name */
BACHNUMB = bprefix + string.Format("{0:d4}", DateTime.Today.Year) + "-" + string.Format("{0:d2}", DateTime.Today.Month) + "-" + string.Format("{0:d3}",bco unter);
/* Create the batch header */
CreateBatchHeader();
}
label2.Text = rc.ToString(); /* Here is the label getting the record count
Application.DoEvents();
rc++; /* Increment the record counter for each transaction to be imported */
dr = dr_cmploop;
/* Get the next AP voucher number */
SqlCommand cmd = new SqlCommand();
Object returnValue;
cmd.CommandText = "SELECT NTVCHNUM FROM PM40100";
cmd.CommandType = CommandType.Text;
cmd.Connection = DataConnection;
returnValue = cmd.ExecuteScalar();
NTVCHNUM = returnValue.ToString();
/* Increment the next AP voucher number */
IncrementNextAPVoucher();
/* Insert the PM Key Master record for each transaction */
CreatePMKeyMaster();
}
DataDataSet.Dispose();
}
public frmIntegratePayables()
{
InitializeComponent();
/* Open the connection */
DataConnection = GetConnection();
/* Parse the import records and insert the payables transactions into batches */
IntegrateTransactions();
}
==========================
Here is the IntegrateTransaction code
private void IntegrateTransactions()
{
/* Set the batch and record counters to 1 */
bcounter = 0;
rc = 0;
/* Define dataset for Transaction Types */
DataDataSet = new System.Data.DataSet();
DataDataSet.CaseSensitive = false;
DataDataCommand = new System.Data.SqlClient.SqlC
DataDataCommand.Connection
DataDataCommand.CommandTex
"coalesce(Reference,'') as Reference,PurchaseDate,Pos
"from PEF_VendorBatchLoadTransac
DataDataAdapter = new System.Data.SqlClient.SqlD
DataDataAdapter.SelectComm
DataDataAdapter.Fill(DataD
DataDataTable = DataDataSet.Tables[0];
foreach (DataRow dr_cmploop in DataDataTable.Rows)
{
if ( rc % 50 == 0) /* Allow no more than 50 transactions per batch. For each 50 transactions create a new batch */
{
bcounter++; /* Increment the batch counter for each 50 transactions */
/* Create the batch name */
BACHNUMB = bprefix + string.Format("{0:d4}", DateTime.Today.Year) + "-" + string.Format("{0:d2}", DateTime.Today.Month) + "-" + string.Format("{0:d3}",bco
/* Create the batch header */
CreateBatchHeader();
}
label2.Text = rc.ToString(); /* Here is the label getting the record count
Application.DoEvents();
rc++; /* Increment the record counter for each transaction to be imported */
dr = dr_cmploop;
/* Get the next AP voucher number */
SqlCommand cmd = new SqlCommand();
Object returnValue;
cmd.CommandText = "SELECT NTVCHNUM FROM PM40100";
cmd.CommandType = CommandType.Text;
cmd.Connection = DataConnection;
returnValue = cmd.ExecuteScalar();
NTVCHNUM = returnValue.ToString();
/* Increment the next AP voucher number */
IncrementNextAPVoucher();
/* Insert the PM Key Master record for each transaction */
CreatePMKeyMaster();
}
DataDataSet.Dispose();
}
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Not a bad idea. First I need to get the program finished so users can do what they have to do. Then I will create fresh code and restructure it. Code is always easier the second time around.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
This is where I have much to learn. I would have preferred to just have functions in a code file and not even have this function assiocated with a form. I need to learn more about how to share code between applications.
ASKER