|
Hi,
I'm trying to read an Excel spreadsheet that contains a variable amount of data, names, address, etc. I will always have columns A-Z, but the number of rows will change. I'm trying to determine the last row in the spreadsheet that contains data. I've tried this code, but it returns a very large number:
public int GetNumberOfRows( )
{
if (excelWorksheet == null)
return (-1);
return (excelWorksheet.Rows.Count);
}
Any help is greatly appreciated.
Glenn
|
|
|
|
|
This might give you some inputs, although not absolutely sure.
My signature "sucks" today
|
|
|
|
|
Good Morning,
I am trying to pass some information to a new page, create a string array, and then use that information in additional code in the application. It seems to work fine until the last step, where the array values seem to disappear (goes null). Somewhere between when the new window closes and I am returned to the original code, I lose the information. I have detailed the process in the code below. Please let me know where I am making my mistake. Thank you in advance for your help, Pat
public frmMain(ArrayList isChecked)
{
InitializeComponent();
this.checkedNames = isChecked;
}
private void buttonWhere_Click(object sender, EventArgs e)
{
for (int iItem = 0; iItem <= listViewColumns.Items.Count - 1; iItem++)
{
colNames.Add(listViewColumns.Items[iItem].SubItems[0].Text);
}
Where w = new Where(colNames);
w.ShowDialog();
foreach (string name in checkedNames)
{
}
}
|
|
|
|
|
Make sure that listViewColumns is not getting set to null in the second page.
My signature "sucks" today
|
|
|
|
|
Abhinav,
Thank you for looking at my dilemma. I am posting the second page code below:
for (int iItem = 0; iItem <= checkedListBox1.CheckedItems.Count - 1; iItem++)
{
string s = (checkedListBox1.CheckedItems[iItem].ToString());
checkedNames.Add(s);
}
frmMain m = new frmMain(checkedNames);
this.Close();
I appreciate any other insight that you might have...Best Regards, Pat
|
|
|
|
|
So, in your frmMain, you have an ArrayList. And a button.
You click the button, and create an instance of your second page, a form called "Where". You then show the form using ShowDialog().
In the form, you merrily add to your ArrayList, and hand it to a new instance of your main form.
Your Where form then closes.
What has happened, is that you new frmMain instance goes out of scope. It is then destroyed. Allongh with it's copy of the ArrayList.
You are then back in your original instance of frmMain, just after your ShowDialog call, and you check the ArrayList. Supprise! It's empty!
Of course it's empty! You added all your data to the local instance you created in the Where form.
What you need to do is when you get back to your original instance, get the arrayList reference from the Where form instance, and copy it to the checkdNames arrayList.
Did you know:
That by counting the rings on a tree trunk, you can tell how many other trees it has slept with.
|
|
|
|
|
The previous answer may not make much sense when you read it. It's is very hard to explain without pictures.
Try this: Use a new sheet of paper every time you use the "new" keyword, and write on it what you have added to it.
Step yourself through your code, and see what happens to your pieces of paper!
Did you know:
That by counting the rings on a tree trunk, you can tell how many other trees it has slept with.
|
|
|
|
|
Griff,
Thank you for taking a minute to explain...yes, I get that. I created a series of stops along the way. That's why I knew exactly where the code went bad. Unfortunately, I do not know what to do next. If I am going to lose the code the second page 2 is deleted (which makes sense), what is the work around? I thought once the arraylist was already created in the constructor, I could "keep it"... . I suppose my knowledge of "reference" is a bit shallow. Since I cannot "keep" the values this way and you seem to fully grasp my predicament, could you please give me a code example that I can use? Thank you...Pat
|
|
|
|
|
OK Griff,
So...now I am in the constructor and the page called 'Where' has not been destroyed yet. So I add code here to make a copy of the Arraylist...but there is a new problem. Now the new 'copy' points to the same memory location as the original. So when the page is deleted, so is the reference for the new copy. Now the question is (I suppose) "How do I copy the old arraylist to a new memory location so that it will survive the destruction of the page and remain?". I think they call it a "deep" copy, and there seems to be a lot of controversy about it. Do you have some code for this?...Thank you, Pat
|
|
|
|
|
You don't need to. As long as there is a single reference to any object, it will not be destroyed - that is one of the major advantages of managed code over unmanaged.
So:
frmMain:
Where myNewForm = new Where();
myNewForm.ShowDialog();
ArrayList myListOfBitsInFrmMain = myNewForm.myArrayListOfBits;
Where:
myArrayListOfBits = new ArrayList();
myArrayListOfBits.Add("Item1");
myArrayListOfBits.Add("Item2");
then "myListOfBitsInFrmMain" contains a reference to an ArrayList with two items. Unless "myListOfBitsInFrmMain" goes out of scope, or your frmMain instance is destroyed, the ArrayList will be available.
Did you know:
That by counting the rings on a tree trunk, you can tell how many other trees it has slept with.
|
|
|
|
|
Griff,
Thank for for your detailed explanation and example. What's even better is that I now have a better understanding of how the arrays work! I have changed the code accordingly and it works perfect. I have marked this as the correct answer. Best Regards, Pat
|
|
|
|
|
Hello,
I need to parse plain Win32 DLL/Exe and need to get all imports and exports from it and to show it on console or GUI(say Win Forms). Is it possible to parse Win32 DLL/Exe in C#.NET, read its export table,import table and get managed types from it. As its unmanaged PE(.NET doesn't allows you to convert unmanaged PE files to managed .NET assemblies, only it generates COM managed assemblies).
So how to parse export and import tables of PE files and take all methods(signatures from it) in managed form.(e.g if char* as argument, it should display as IntPtr)
Regards
Usman
|
|
|
|
|
IMO that is impossible. A native code DLL or EXE file (which uses PE format) normally contains an import and an export table, containing the names of the functions; there is no information about the parameters nor the return type, except maybe, those are to some extent encoded in the C++ name mangling. The mangling is not complete; only some info is available.
Furthermore, a lot of Windows DLLs export functions by number ("ordinal number") rather than by name.
Next, you need to know what the calling convention has to be (CDecl, StdCall, ...). That information is not present, unless you start studying the assembly instructions.
And finally, when using P/Invoka to call a native function from a managed language, one can, and often does, create several prototypes, all mapping to the same function, but taking different parameter types. A typical example would be SendMessage().
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
glitteringsound wrote: I need to parse plain Win32 DLL/Exe and need to get all imports and exports from it and to show it on console or GUI(say Win Forms). Is it possible to parse Win32 DLL/Exe in C#.NET, read its export table,import table and get managed types from it. As its unmanaged PE(.NET doesn't allows you to convert unmanaged PE files to managed .NET assemblies, only it generates COM managed assemblies).
You need to understand, EXACTLY, the Windows PE format. From there, you can write your own library that can parse the file, byte by byte. I've done it myself. No, you can't have the code.
You can start by reading this article[^] and the article it links to. There is also a PDF file that I found that goes into more detail. You can get it from here[^].
Now, you can only get the function names of the import and export tables. There is no information at all inside a PE file that contains anything about the parameters passed or expected by those functions.
|
|
|
|
|
hi, When adding items to a listview, I want the last added item on top instead of bottom. How can I achieve that? Thanks in advance
By the way, when I use sorting property (ascending or descending), everything mess up
modified on Sunday, May 23, 2010 10:18 AM
|
|
|
|
|
Either add the items in reverse order or use Insert(index,item) rather than Add(item) .
CQ de W5ALT
Walt Fair, Jr., P. E.
Comport Computing
Specializing in Technical Engineering Software
|
|
|
|
|
If you are assigning a collection to a listview, you could move the last item of your collection to the first and then assign to the listview. Or else, you could use a temporary collection to build a list in the order you want and then assign to this listview.
My signature "sucks" today
|
|
|
|
|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace 用户管理
{
public partial class ChangestaffPwd : Form
{
public int flag;
public string str;
public ChangestaffPwd()
{
InitializeComponent();
}
//-----------在DataGridView控件下面textBox控件显示内容-----------
private void show()
{
try
{
this.textBox1.Text = this.dataGridView1.CurrentRow.Cells[0].Value.ToString();
this.textBox2.Text = this.dataGridView1.CurrentRow.Cells[1].Value.ToString();
}
catch (Exception ex)
{
MessageBox.Show("错误描述如下:\r\n" + ex.Message, "不能对列进行排序");
}
}
//---------------DataGridView控件随着选中行的不同,显示不同的内容-------------------
private void alternate()
{
if (this.dataGridView1.Rows.Count != 0)
{
for (int i = 0; i < this.dataGridView1.Rows.Count; )
{
this.dataGridView1.Rows[i].DefaultCellStyle.BackColor = System.Drawing.Color.Orange;
i += 2;
}
}
}
private void ChangestaffPwd_Load(object sender, EventArgs e)
{
SqlConnection con = DBCon.createCon();
SqlDataAdapter sda = new SqlDataAdapter("select StaffID as 用户名,Password as 密码 from Staff ", con);
DataSet ds = new DataSet();
sda.Fill(ds, "table");
this.dataGridView1.DataSource = ds.Tables[0].DefaultView;
show();
}
private void button3_Click(object sender, EventArgs e)
{
if (button3.Text == "添加")
{
this.textBox1.Enabled = true;
if ((str = this.textBox1.Text.ToString()) != "")
{
if (MessageBox.Show("您确定要添加本条记录吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
{
flag = 1;
MessageBox.Show("请输入用户名和密码并且按确定按钮,才能添加成功!");
return;
}
}
}
}
private void button2_Click(object sender, EventArgs e)
{
if (button2.Text == "修改")
{
if ((str = this.textBox1.Text.ToString()) != "")
{
if (MessageBox.Show("您确定要修改本条记录吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
{
flag = 2;
MessageBox.Show("请按确定按钮,才能修改成功!");
return;
}
}
}
}
private void button4_Click(object sender, EventArgs e)
{
if (button4.Text == "删除")
{
if ((str = this.textBox1.Text.ToString()) != "")
{
if (MessageBox.Show("您确定要删除本条记录吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
{
flag = 3;
MessageBox.Show("请按确定按钮,才能删除成功!");
return;
}
}
}
}
private void button5_Click(object sender, EventArgs e)
{
if (button5.Text == "确定")
{
if (flag == 1)
{
SqlConnection con = DBCon.createCon();
con.Open();
//在原表中新建一个新行,然后再数据添加到新行中
SqlCommand cmd = new SqlCommand("insert into Staff values(@StaffID,@Password)", con);
cmd.Parameters.Add("@StaffID", SqlDbType.Char, 10).Value = textBox1.Text;
cmd.Parameters.Add("@Password ", SqlDbType.Char, 20).Value = textBox2.Text;
cmd.Connection = con;
cmd.ExecuteNonQuery();
con.Close();
SqlDataAdapter sda = new SqlDataAdapter("select StaffID as 用户名,Password as 密码 from Staff", con);
DataSet ds = new DataSet();
sda.Fill(ds, "table");
this.dataGridView1.DataSource = ds.Tables[0].DefaultView;
this.textBox1.Enabled = false;
MessageBox.Show("添加记录成功!");
this.textBox1.Enabled = false;
try
{
show();
}
catch (Exception ex)
{
MessageBox.Show("错误描述如下:\r\n" + ex.Message, "没有记录显示!");
}
flag = 0;
}
if (flag == 2 && str != "")
{
SqlConnection con = DBCon.createCon();
con.Open();
SqlCommand cmd = new SqlCommand("update Staff set Password ='" + textBox2.Text.ToString() + "' where UserName='" + str + "'", con);
cmd.Connection = con;
cmd.ExecuteNonQuery();
con.Close();
SqlDataAdapter sda = new SqlDataAdapter("select StaffID as 用户名,Password as 密码 from Staff", con);
DataSet ds = new DataSet();
sda.Fill(ds, "table");
this.dataGridView1.DataSource = ds.Tables[0].DefaultView;
try
{
show();
}
catch (Exception ex)
{
MessageBox.Show("错误描述如下:\r\n" + ex.Message, "没有记录显示!");
}
MessageBox.Show("修改成功!");
flag = 0;
}
if (flag == 3 && str != "")
{
SqlConnection con = DBCon.createCon();
con.Open();
SqlCommand cmd = new SqlCommand("delete from Staff where StaffID='" + str + "'", con);
cmd.Connection = con;
cmd.ExecuteNonQuery();
con.Close();
SqlDataAdapter sda = new SqlDataAdapter("select Staff as 用户名,Password as 密码 from Staff", con);
DataSet ds = new DataSet();
sda.Fill(ds, "table");
this.dataGridView1.DataSource = ds.Tables[0].DefaultView;
try
{
show();
}
catch (Exception ex)
{
MessageBox.Show("错误描述如下:\r\n" + ex.Message, "没有记录显示!");
}
MessageBox.Show("删除成功!");
}
flag = 0;
}
}
private void button10_Click(object sender, EventArgs e)
{
if (button10.Text == "退出")
{
this.Close(); //退出普通用户密码管理维护
}
}
private void dataGridView1_SelectionChanged_1(object sender, EventArgs e)
{
show();
}
private void button1_Click(object sender, EventArgs e)
{
SqlConnection con = DBCon.createCon();
SqlDataAdapter sda = new SqlDataAdapter("select StaffID as 用户名,Password as 密码 from Staff where Username like'" + "%'", con);
DataSet ds = new DataSet();
sda.Fill(ds, "table");
this.dataGridView1.DataSource = ds.Tables[0].DefaultView;
try //有时找不到匹配的记录,有异常
{
show();
}
catch (Exception ex) //对异常进行处理
{
MessageBox.Show("错误描述如下:\r\n" + ex.Message, "没有找到匹配的记录");
return;
}
}
}
}
|
|
|
|
|
It is impossible to read through all that code.
Where (and what) are you getting the error?
My signature "sucks" today
|
|
|
|
|
I did not read that, it is unreadable without proper formatting; please edit and put the code in a big pair of <PRE> tags.
And provide an explanation: what is it you want? what is happening? what are the symptoms? in what line does it fail?
in summary: please read the "how to get an answer" guidelines near the top of this forum.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
modified on Sunday, May 23, 2010 9:45 AM
|
|
|
|
|
In a class there are private fields and several threads all member of the class.
Does it need to lock read access to class fields to avoid reading only of the class members from several threads at the same time.
Чесноков
|
|
|
|
|
Reading is only a problem if there is a possibility that the value of a field may be changed by another thread during the read. If so, then yes you will need to lock it.
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
I've got BackgroundWorker thread in my application which is started in timer event with 10ms interval. It takes about 50ms or larger for a thread to complete. I'm using smaller timer interval to start new thread as soon as possible after previous completed.
I've got IsBusy() method call in timer event to avoid new thread invocation with RunWorkerAsync() if previous is busy by all means.
But in one machine I'm testing it IsBusy fails somehow. Thus before previous thread finished RunWorkerAsync() is called again on the same running Background worker resulting in:
System.InvalidOperationException in Void RunWorkerAsync(System.Object):
Because it is currently too busy, can not perform multiple tasks simultaneously.
How that is possible?
Чесноков
|
|
|
|
|
The IsBusy property is set when you call RunWorkerAsync and isn't unset until immediately before RunWorkerCompleted is raised.
I would start your Timer in your RunWorkerCompleted handler after any other tasks being performed in there so the issue is avoided altogether as there would be no need to check IsBusy at all.
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
There is one thread function and an array of BackgrounWorkers.
There might be N workers running on the same thread function.
On every timer event all array memeber are queried for IsBusy to start new worker.
Timer even reset in RunWorkerCompleted will be hard to handle.
I wonder the reason for IsBusy failure if it is set up immediatly after RunWorkerAsync call?
Or it is set up as the thread enters its function?
Чесноков
|
|
|
|
|