|
Hi Roni,
I think that I understand your question but cannot help at the moment because after a quick look through your database I cannot see anything resembling a Stock Control/Inventory system.
If there is one, please tell me where it is and I will have another look.
If you haven't got as far as creating one yet then can I suggest that you take a look at Inventory Management Database[^]. Download it and take a look at the tables and the one view it contains. This is a pretty good example of the sort of structure(s) that you will need to implement.
If you do not like that one, or are just interested, take a look at Inventory Templates[^], from the same site. You will see that many of them are Excel templates but there are a few Access ones (Inventory, HomeInventory, Book Collection, Wine Collection). The first one (Inventory) is just an *.accdt file and as I do not have Access I am not able to look at it to see if it is more suited for you than the one in the paragraph above.
Write back, when you have had a think.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
Hi Henry
The purpose of the Qty In Stock & Status is to control the food and drinks on application at run time.
Basically if for instance there are only 10 portion of Soups, what I want to do is go to that StockIn form
(I mentioned on my previous question) and controll it like so...
this is the datagridview what it should look like (after you click the starter button)
===============================================================
FoodName FoodType Qty In Stock Status
===============================================================
Olives Starter 0 <Allways on Stock>
Soup Starter 0 <Allways on Stock>
etc... etc... etc... etc...
===============================================================
and this is a datagridview what it should look like when you controll the stock of your food at run time...
===============================================================
FoodName FoodType Qty In Stock Status
===============================================================
Olives Starter 0 <Allways on Stock>
Soup Starter 10 <Controlled>
etc... etc... etc... etc...
===============================================================
So basically what I'm trying to achieve is, as soon as I load the database records for instance Starters
(see above the 1st datagridview) click on the cell under the Qty In Stock Column of the Soup Row
(see the 2nd datagridview) pop up a dialog form and enter the quantity of that food,
and then take that number (num 10) and displayit on the button (called Soup) of the first form the one with the restaurant menu.
Please Henry let me know if you don't understand my question....
Kind regards
Roni
|
|
|
|
|
Hi,
Well, I thought I understood it before although it seems that I didn't.
Once again, I think I understand it but I do not see from where you get the 10 Soups. Unless they are purely fictitious Soups.
Basically, you want the user to click the cell, enter a number in the dialog (could be any number, even 3000, doesn't matter), click OK. The number then gets entered into the grid and then also gets displayed on the soup button on the previous form.
Please confirm that is what you want.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
Hi Henry
Yes that is what I want...
Roni
|
|
|
|
|
Roni,
The first part of what you want is fairly simple.
Write an event handler for the DataGridview.CellClick or DataGridView.CellDoubleClick events. I have done it here for the Click event but after writing it I thought that it would actually be better on the DoubleClick one, quite simply because that way you can be sure the user meant it and didn't accidentally or aimlessly click in the grid. It is up to you. The code will be the same for both events.
This code uses InputBox , code below.
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 1)
{
string cellContent = "0";
if (this.dataGridView1[e.ColumnIndex, e.RowIndex].Value != null)
{
cellContent = this.dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString();
}
using (InputBox ib = new InputBox("Enter new stock amount:", this.dataGridView1[0, e.RowIndex].Value.ToString(), cellContent))
{
if (ib.ShowDialog() == DialogResult.OK)
{
this.dataGridView1[e.ColumnIndex, e.RowIndex].Value = ib.Result;
cellContent = ib.Result;
}
}
}
}
This is a small Form with a Label (lblPrompt), a TextBox (txtResult) and two Button s (btnOK, btnCancel). The FormBorderStyle is set to FixedDialog
public partial class InputBox : Form
{
public InputBox(string text, string caption, string defaultValue)
{
InitializeComponent();
this.Text = caption;
Size size;
using (Graphics g = this.CreateGraphics())
{
Rectangle screen = Screen.PrimaryScreen.WorkingArea;
SizeF sizeF = g.MeasureString(text, lblPrompt.Font, screen.Width - 20);
size = sizeF.ToSize();
size.Width += 4;
}
if (size.Width < 200)
{
size.Width = 200;
}
Size clientSize = this.ClientSize;
clientSize.Width += size.Width - lblPrompt.Width;
clientSize.Height += size.Height - lblPrompt.Height;
this.ClientSize = clientSize;
lblPrompt.Text = text;
txtResult.Text = defaultValue;
this.DialogResult = DialogResult.Cancel;
}
void CancelButtonClick(object sender, System.EventArgs e)
{
result = null;
this.Close();
}
void AcceptButtonClick(object sender, System.EventArgs e)
{
this.DialogResult = DialogResult.OK;
result = txtResult.Text;
this.Close();
}
string result;
public string Result
{
get
{
return result;
}
}
}
The problem comes in trying to make the new value available for the 'Soup' button later. If you were only going to enter one new value and the Form with the Soup Button was on the calling form, OK. But there is no guarantee that the Soup Button Form is anywhere in the calling-chain for this operation and it is also likely that more than one new value will be entered at the same time, (Soup-10 and Olives-20 and AntiPasti-5 and so on). Therefore the only sensible approach says that these values should be stored somehow, so that when the Soup Button Form is opened the values are available.
Also if you are going to put the quantity on the buttons it would be better if it was available when the application first starts.
All of this stipulates that there must be some form of stock control mechanism in the application, even if it is as simple as adding a 'Qty' column to the food table, although this is not the best way to do it.
Let me know what you think.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
Hi Henry
The InputBox class is a saparate class or is it inside the scope of the StockIn class
|
|
|
|
|
Separate.
Just add a Form to your project.
It is even worth putting it in a project of its own since it can be used in many situations.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
ok
I will let you know shortly whats going on
thanks a lot
Roni
|
|
|
|
|
Hi Henry
I have tried the code that you supplied but it's not showing the number in the button e.g. Soup
|
|
|
|
|
I explained that this was just for the first part - getting the number from the user.
I also explained that without storing this value, it was not possible to add it to the button.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
Oh ok sorry I didnt understand that
|
|
|
|
|
Think about a situation where the user of your application goes to the 'Manage->Stock In' screen and adds to the Soup, Olives and several other items. How can all that information be passed back so that it is available to the Soup button, the Olives button and all the others. Without a massive List<> or array it cannot really be done.
It might just be possible if there was a Dictionary<foodItem, quantity> with global scope so that both the 'Stock In' Form and the 'Starter Button UC' could 'see' it but then you would have a situation where the buttons for the items selected by the user (Soup, Olives etc) would have a number but none of the other buttons would. Which would look very odd! (I could show you how to do it this way, but I would not be helping you properly. I would be showing you bad practices, which I don't like doing.)
Also, so that the numbers would appear next time the app was started there would have to be some mechanism to serialize the dictionary when the app closed and deserialize it when the app starts up again. Very messy. It is a Database backed Application so use the Database instead. As things are, you are moving to the situation that causes applications to get to the stage where no-one can maintain them because there are work-arounds to get round the work-arounds to get round the work-arounds, and so on.
You should pause now and consider ALL of the features that you are going to want in this app and design a Database that will be able to cope with them. While you are paused you should also consider the fact that your project is getting incredibly large, not over all but the number of files it contains. There is a very strong case here for removing all of the Data Access code from the current forms and putting it into a separate project. The Forms and UCs would then call a method in that project and have a DataTable, or List/Array depending on their needs, returned that they would work with.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
Hi Henry
Ok can you advise me how to do it and what to do next
kind regards
roni
|
|
|
|
|
Hi Roni,
Well, as I said in my last message think about all of the things that you want the application to do and decide which parts of each of those things you want to do for real and which of them you want to only do partially and simulate the rest. A lot of this will depend on if your application is for use in the real world or just for your education/amusement or whatever.
To use this 'showing the in-stock number on the buttons' feature as an example. (this is how I see it BTW, you may see it differently)
1 You want the number displayed.
2 It therefore makes sense for it to be there when the app starts up.
3 For that to happen the numbers should either be stored somehow and real numbers used or they should be totally made up so that every button gets say 10 at start up.
4 Should the number decrease every time that item is ordered.
5 If they decrease, what should happen when the number reaches zero. Should it automatically get topped back up to 10 or should the user have to do something. If automatic will they be real stock or just a number. If automatic and it is real stock what happens if there are none in stock to top up the button with. If the user has to do something should it be like it is now or might it be better if there was a context menu for each button with a 'Replenish Stock' item that would put up the InputBox type thing so that the user just tops up that button.
And so on. Once you have decided all these things you will have a better idea of what needs to be done.
As far as the separate project for the Data Access stuff is concerned. There are currently 4/5 or even more places where a OleDbConnection is created, used and then disposed. There should be just one method that returns an OleDbConnection when it is called (just for example lets say it is called GetConnection(). The ConnectionString should be stored in the *.config file (encrypted) and that should be the only one that is used. If a particular Form needs a list of the Starters it should call a method called something like GetCourseMenuData() and pass in a string "Starter" and get back a List, an Array or a DataTable with the data it needs. If another Form/UC needs the Desserts it should call GetCourseMenuData("Dessert"). GetCourseMenuData() should call GetConnection() and dispose of it when it is done. There should be no need to call GetConnection() from any of the Forms or UCs in the User Interface part of the Application.
By doing these things when there is a problem with getting a connection you know that the bug/problem can only be in one place in your code.
Have a think about it and let me know when you are ready to start and which part you want to start on. Even if you decide to carry on as it is now, I will try to help where I can.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
Hi Henry
Going back to step number 4 of your last question,
-As a matter of fact yes the number has to be decreased on the button every time the user orders that item,
and on step 5:
-Well basically when it reaches zero to disable that button (such as enable = false), or draw sort of X (diagonally) accross that button,
-It doesnt have to be topped up automatically.
Let me explain in another way....
Say for instance the Manager asks the chef in the kitchen about food items, and the Chef sas to the Manager I have only 10 soups for dinner,
What the Manager should do then notify all the waiters that there are only 10 soups for dinner,
And then the Manager should go to the computer system (in this case my project for insatance)
Click the:
-Manage button, then
-StockIn button, then
-Select Starter Button (the items get displayed to datagridview)
-Double click the particular datagridview cell (in this case the Soup)
-Insert qty num for that item (such as 10)
-And that number should be displayed inside the Soup Button.
(a) Now if all 10 soups get ordered (for instance by customers) the number should be decreased untill reaches zero and enable = false that button.
This what the DatagridView should look like before Manager takes action...
===============================================================
FoodName FoodType Qty In Stock Status
===============================================================
Olives Starter 0 <Allways on Stock>
Soup Starter 0 <Allways on Stock>
etc... etc... etc... etc...
===============================================================
This what the DatagridView should look like after Manager takes action...
===============================================================
FoodName FoodType Qty In Stock Status
===============================================================
Olives Starter 0 <Allways on Stock>
Soup Starter 10 <Controlled>
etc... etc... etc... etc...
===============================================================
(b) But in the mean time (this is reverse scenario) if Chef can manage to make more soup for that dinner and tells the Manager that he has enough soup, then the manager should go back do the same procedure and enable = true the soup button.
And finally this what the DatagridView should look like (read step (b)) when Manager takes action....
===============================================================
FoodName FoodType Qty In Stock Status
===============================================================
Olives Starter 0 <Allways on Stock>
Soup Starter 0 <Allways on Stock>
etc... etc... etc... etc...
===============================================================
in the mean time I would like to carry on as it is now I hope you dont get upset
Kind regards
roni
|
|
|
|
|
Hi Roni,
Just to let you know that I have seen your latest message.
I've been too busy today but I have had a couple of ideas and I'll try them out tomorrow before contacting you.
In the mean time, if you don't already know, it would help if you tested the buttons to see if they will take a two line text, so that you can have 'Soup' on the top line and the number on the next one.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
Hi Henry
I just cam back from work.
I read your message and I tried the code last night and today aswell but it doesn't show the number on button...
Kind regards
roni
|
|
|
|
|
Hi Henry
Are you online
Roni
|
|
|
|
|
Hi Roni,
Yes.
I was going to call you later.
What can I do for you?
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
Im trying to sort this datagridview for a quite sometime and its doing my heading...
|
|
|
|
|
Well, as I said the other day I have had two ideas.
1) Add a column to the Food Table and the Drink Table 'QtyInStock' to hold the information. Although as I don't know how you calculate(?) the data for the Status field I can't advise on that at the moment.
2) Implement a Dictionary (or similar Collection) to hold the information and read it in when the application starts and write it out to disk when the app closes.
Both of these will involve quite complex changes to the code.
With 1), to make it work properly you would have to at least do part of what I mentioned a while ago and move the Data access stuff out into a separate project so that you can then be sure that both the StartersUC (and MainsUC and DessertUC etc.) and the Stock-In form are guaranteed to be looking at the same DataSet/DataTable so that when you update the data in Stock-In the UCs get notified and can update their buttons. Similarly when the buttons decrease the number the next time you go to Stock-In it sees the new figures.
With 2) to ensure that all the Forms/UCs etc. that need to are looking at the same collection it would have to be implemented as a Singleton Class. There is also the Serialization and Deserialization to be dealt with.
As I say, both will require substantial changes to the existing code because the application was not designed from the start to allow for this sort of thing. It has sort of just grown little bits to deal with specific problems in isolation, not as a part of the whole application. It is nobody's fault. It is a result of having asked for help about a specific thing, getting a helpful response and coding to that. The problem is that the responders had no idea how their suggestions would impact on the other parts, because they did not know about them.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
Hi Henry
How are you, just wanted to say hello...
kind regards
roni
|
|
|
|
|
Hi there Roni,
Sorry for the delay in replying. I moved your message somewhere safe so I could reply later and forgot where I put it.
I'm OK. Hope you are too.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
When you're wrestling a gorilla, you don't stop when you're tired, you stop when the gorilla is.
|
|
|
|
|
Hi Henry
How are you, I hope you ok too
roni
|
|
|
|
|
Hi Henry
are you still online
I need to ask you something if possible
kind regards
roni
|
|
|
|
|