How to interact between two tables on both directions in Excel? - vba

I have 2 sheets in my Excel project:
In "Sheet1", I have a big data table, with 4 columns:
DataTable[Country], DataTable[Brand], DataTable[Parameter], DataTable[Calculated].
On "Sheet 2" I have a dashboard. I have there a table called FilteredTable that presents the data from DataTable. I have there a drop down command that lets the user select country, and the table is filtered accordingly.
I want that the FilteredTable will not only show data from the original DataTable, but to let the user to change the [Parameter] column. When changing it, I want that the [Calculated] column in both tables will be updated accordingly. If the user will change the country, then the FilteredTable will show the parameter that is stored in DataTable for that combination of [Country] and [Brand]. And if the user will get back to the first country, the displayed parameter will be the last one that the user entered.
I am a bit confused how to do it.
What I have done so far is:
1) to read into FilteredTable rows from DataFilter, using a formula array. I am mirroing this way [country],[brand] and [calculated]
2) in the DataTable[paramter], I read from FilteredTable[parameter] the same way, with a formula array.
It works fine, untill I change a country, and then the parameters in FilteredTable are already do not match the new country, and in DataTable, the parameters for the old country where changed to 0.
I'm in a logical loop. Is there a way out?
Thanks

Have you considered using 3 tables instead of 2? This would be: the original data table, a table which pulls in all values created through manual entry from the display table, and the display table itself.
In VBA, create a function which runs each time a formula is changed in the display table. That function should take the new data from the user, and copy the altered row onto the 'manual entry' table. For the display table itself, you could either recalculate manually through VBA every time a change is made, or have a formula which looks to see whether there is data in the manual table. If there is data in the manual table, that is where the value is pulled from. Otherwise, data is pulled from the original data table.

Related

VB.net add DataTable rows to DataGridView

I've tried to find a solution to this, but can't seem to find anything that quite matches my goal here. The answers I've found are either C# or are wanting the data to go from the DGV to the DT.
I have a datatable, which is built out using an SQL query. In this data table, I have a column "Lab ID" that I want to use as a search index. On my front end, there is a requirement for the Lab ID to be supplied. When the Lab ID is entered, the data table should be searched, and the resulting row (entire row) should be added to the datagridview. Each scan should add a row and not overwrite. I have specified the DGV columns at form load but would like it to grab the column names from the table if possible.
Here is my current front end - noting that the left datagridview is only temporary to confirm the data is coming out of SQL and references the same datatable I am wanting to use for the right DGV. The user will pick the dates, enter the Lab ID, then click Check. If the Lab ID checks out, it should be added.
The other thing I'll need to able to do is compare the results in the data table with what is in that datagridview - if an item in the table is missing in the datagridview, I need to be able to retrieve the missing Lab IDs (don't need the whole row for this one) and add those missing Lab IDs to a messagebox.
I don't have any code at this point because I've not found anything that works, with the exception of this:
dgScanned.Rows.Add(GetResults.Rows)
Which results in the string 'System.Data.DataRowCollection' being added to the 'Request ID' column.

Create table without omitting empty rows?

I have a short question but no reproducible sample as I simply use the standard function for now.
I want to use SQL's CREATE TABLE function. However, I want the table to display rows even if there are no data points for that specific ovbservation. Currently, whenever there is no data for a certain row, the whole row gets omitted. Ideally I'd like it to still display the row for that specific date, and just have empty cells wher ethe data is missing.
This is important because I need the table to be of specific size, even if data is missing.
One idea I had was to include a WHERE ROWNUM statement, which refers to a materialised view or table of exactly the size I want the table to be in. Is this possible? Any other solution is welcome.
Create table first of all.
use insert statement to insert all the required rows at once (empty rows with only date, or rowindex)
'View' idea is not better, because you have to show those record (empty rows to enter data perhaps) to user, so if user enters data in 5th rows, you will not be able to add 5th row in table prior to first 4 rows.

#REF! result when using INDEX function in Excel

I am trying to create a couple of reports from data on another Excel worksheet based on the value in a drop down list. I am using the MATCH and INDEX functions and have created Named Ranges of the columns of data. I am able to get the first value I want in the report but none of the others, even though when I debug by evaluating the formula it points to the right cell but still displays #REF! instead of the actual value from the referenced cell.
I'll do my best to make this clear:
In "POST_Data" worksheet I have 4 columns titled Course Name, Course Length, Attendee and Date Attended. Currently I have 33 rows of data (plus the header row) but I need the reports to be dynamic since new data will be added from time to time.
I have created Dynamic Named Ranges of the data using the OFFSET function (e.g. for the Course Name data I have a NameRange called CourseNamesData = OFFSET(POST_Data!$A$2,0,0,COUNTA(POST_Data!$A:$A),1)
In the "DashBoard_and_Data Entry" worksheet I have a two report areas: one to report the Course Name and Date Attended for a specified Attendee (specified by a drop down list in cell C7) and the other report to provide the Attendee Name and Date Attended for a specified Course Name (specified by a drop down list in I7).
In row 8 I report the column that the data belongs to in the POST_Data worksheet
What IS working: When I choose an Attendee from the drop down list in C7, I correctly report the first of the Course Names for this attendee from the data in the POST_Data worksheet. I used the following formula to do so: =INDEX(CourseNamesData,MATCH(C7,AttendeeNamesData,0),B$8)
What is NOT working: The corresponding "Date Attended" data when I use a similar formula as the one that is working. I have: =INDEX(DateAttendedData,MATCH(C7,AttendeeNamesData,0),C$8) but this gives me the #REF! error.
Again, when I try to follow the data that this formula points to, it looks like it is pointing to the correct cell but not showing the result.
Another issue is how to get all the data corresponding to the choice in the drop down and not just the first row. So for example, if I choose Richards, K. from the attendee list and he has attended 4 training courses, I need all 4 to show up, not just the first one.
I appreciate any help or insights on this. If you know of a better way to display the workbook contents, please let me know.
Thanks!
Can you provide a screenshot so that I can better understand the issue?
With regard to your post_data worksheet, you might find it easier to turn the data into a table. You can then point your named range to the column within the table without needing to use the offset function, and your range will update automatically as you add to the table.
I have a entire playlist on my youtube channel devoted to using ranges and tables if you are interested. https://www.youtube.com/playlist?list=PL1nLTDk2QLL9415OPSjIICJs1EeV-HeK3

MS Access Delete query based on combobox

I have a table with a bunch of different fields. One is named period.
The period is not part of the raw data but I run a query when I import new data to the database that gives each record a period.
Now I need a delete query that will delete all the records that have the same period as what is selected in a combobox.
The values in the combobox come from a calendar table that contain all the possible values that could be in that period column at any time.
This is the basic query i thought would solve this issue but it tells me it is going to delete 0 rows every time I run it:
DELETE *
FROM PlanTemp
WHERE PlanTemp.period = Forms![Plan Form]!Combo163;
If you don't need the key field, just remove it.
Look at the "PROPERTIES" section and look at the column names.
Ether remove it there, or from your QUERY source.
You can also look at the Data section of the properties, and change your BOUND column, to Column 2... or whatever holds the data you want to use.

How can I bind a multi-row update or insert statement to a form?

I have a table Prices:
ID -- primary key, autonumber long integer
PriceDate -- Date
Price - Currency
Quantity - Number, DECIMAL subtype
UnitPrice - Number, DECIMAL subtype (an update statement is run to keep this in synch with price and quantity, but it's just a convenience for indexing... probably it'll be replaced with an expression in my queries)
ItemNote - Text
NewStores_ID - long integer key, lookup to another table of stores
NewItems_ID - long integer key, lookup to another table of items
To enter prices for a given store on a given day, I would like to be able to select the store and date ONCE on a form, then enter the items individually in a datasheet. For reasons unexplained, this proves difficult.
I can create a subform binding everything but the store and price to a temp table TempPrices with the same structure as the original. Then I run the SQL statement
INSERT INTO Prices
(PriceDate,Price,Quantity,UnitPrice,Brand,ItemNote,NewStores_ID,NewItems_ID)
SELECT
PriceDate,Price,Quantity,Price/Quantity AS
UnitPrice,Brand,ItemNote,NewStores_ID,NewItems_ID)
FROM Temp_Prices;
This will feed all the new rows into the main table. But, when I want to set the store and date only once, I run into problems. I've tried using named parameters for date an store in the insert statement... which can cause a pop-up prompt, but I cannot bind it to a form control. I've tried binding an update statement for those fields in the temp table to a form... but it doesn't even show an option to bind a multi-row update.
How can I get this to work with a minimum of clumsy hackery? It seems like there ought to be a simple solution, and if I were using something like PHP or JDBC I'd just run an extra query.
Edit: changed storage type for Quantity and UnitPrice to Number, Decimal subtype in place of double float. Just so people won't cry about using a float in any proximity to currency. It doesn't pose a problem in my use, but there are enough people who have a knee-jerk reaction to that.
Edit 2: Form/Subform
I'm trying to structure this as a master form with a either fields for entering store name and date, or a subform for the same, then a subform mapping to the temporary table for entering pricing data. There is an action button to run the insert/update queries to dump the temp table into my main prices table and clear out the temp table. However, the problem is that I can't figure out how to get the date/store fields in the master (or subform) to bind to an insert/update value applied to all the new rows at once.
Edit 3: SQL Statements (for clarity)
INSERT INTO
PRICES(NewStores_ID,PriceDate,NewItems_ID,Brand,Price,Quantity,
UnitPrice,ItemNote)
SELECT
#MyStore_ID,#MyPriceDate,NewItems_ID,Brand,Price,Quantity,
Price/Quantity,ItemNote
FROM TempPrices;
UPDATE TempPrices SET PriceDate=#MyPriceDate,NewStores_ID=#MyStoreID;
For these queries, I cannot bind parameters for #MyStore_ID or #MyPriceDate to fields in any form. The queries don't show up as options when trying to link them to a form. I can run them and get popup boxes to input parameters, but that's not what I want.
This is the target I'm aiming at:
"I would like to be able to select the store and date ONCE on a form, then enter the items individually in a datasheet."
However, if you have a reason why you need to do it with a temp table and DML statements, then this suggestion will not be useful.
I created a Prices table with only 4 fields, then a query on that table which I used as the Record Source for a form, "fsubPrices":
SELECT p.ID, p.NewStores_ID, p.PriceDate, p.Price
FROM Prices AS p
ORDER BY p.NewStores_ID, p.PriceDate;
The form has text boxes (txtNewStores_ID, txtPriceDate, and txtPrice) bound to the similarly-named query fields. I set Enabled=Yes for txtPrice, and Enabled=No for the other two.
Then I created an unbound form "frmPrices", and in the form header added a combo box "cboStores" and a text box "txtPriceDate". The combo has Bound Column = 1 with this query for its Row Source:
SELECT l.Store_ID, l.Store_name FROM tblkupStores AS l ORDER BY l.Store_name;
Then I added fsubPrices as a subform control to the detail section of frmPrices. The tricky part is setting the Link Master/Child Fields. There is a "wizardy dialog thing", but it will only allow you to select from the available fields, and I needed to link controls on the main form with fields on the subform. To do that, I had to type what I wanted directly into the subform control's property sheet:
Link Child Fields......NewStores_ID;PriceDate
Link Master Fields.....cboStores;txtPriceDate
The result is ... choose a store and date combination in the main form ... any matching records are displayed in the subform. You can navigate to the "new record" in the subform to add records for that store/date combination. But the txtNewStores_ID and txtPriceDate controls don't show the updated values until the new record is saved.
I hope this is close to what you want. It's actually fairly quick and easy to create; not so easy to describe.
You can't really do that. You are always going to have one row being worked with at a time.
What you can do is simulate it by changing the form's Default View from "Single Form" to "Continuous Form" or perhaps "Data sheet" and making is a child(sub) form of a master form.
Then you can put the store and date on the Master form, and linking to the child form using the NewStores_ID and PriceDate fields.