In my simple WinForm application I have a ContextMenuStrip. This is palced during design time and few items have been added in designer mode. For example following items are added during design time,
--------
Option 1
Option 2
Option 3
--------
Close
Exit
Now I am getting the Groups from database. Each Group can have multiple users. So first I create the Groups using this code,
For Each drGroup In dtGroups.Rows
Dim groupMenu As New ToolStripMenuItem() With {.Text = drGroup ("GroupName"),
.Name = RemoveWhitespace(drGroup ("GroupName"))
}
myCMS.Items.Add(groupMenu)
Next
I am not mentioning the code for adding sub items for groups as it is beyond the context of this question. Now my context menu strip is like this,
--------
Option 1
Option 2
Option 3
--------
Close
Exit
Group 1
Group 2
Group 3
Group 4
Group 5
But I want the output like this,
Group 1
Group 2
Group 3
Group 4
Group 5
--------
Option 1
Option 2
Option 3
--------
Close
Exit
I have no idea how I can achieve this. One way could be to remove the existing items and re-add them after all dynamic items are created but is there any other solution.
Instead of adding items, you can simply insert them into the beginning of the list:
myCMS.Items.Insert(0, groupMenu)
This will change the "index" values of the existing items in the current list.
Related
I have a table with purchase orders, and all POs could have several entries with different items associated.
PO
PN
Status
1
A
Open
1
B
progress
1
C
Delivered
2
A
Open
3
A
Delivered
3
A
Delivered
From this master data Table, I would like to create a overview table, with just one entry per PO and only one Status information, according certain criteria.
Criteria example:
if one item is in PROGRESS or DELIVERED set PO status as PROGRESS
if one item is in OPEN (But don't exist PROGRESS) set PO Status as OPEN.
if all item is in PROGRESS or DELIVERED or OPEN set PO Status as PROGRESS or DELIVERED or OPEN accordingly.
OVERVIEW TABLE Example:
PO
Status
1
PROGRESS
2
OPEN
3
Delivered
I will offer one approach to consider. Assuming there are only 3 status categories:
Query1:
SELECT OrderDetails.PO,
Count(OrderDetails.PN) AS CntPN,
Sum(IIf([Status]="Progress",1,0)) AS CntP,
Sum(IIf([Status]="Open",1,0)) AS CntO,
Sum(IIf([Status]="Delivered",1,0)) AS CntD
FROM OrderDetails
GROUP BY OrderDetails.PO;
Query2:
SELECT Query1.PO, Switch([CntP]=[CntPN],"Progress", [CntO]=[CntPN],"Open", [CntD]=[CntPN],"Delivered", CntO>0 AND CntP=0,"Open", CntP>0 Or CntD>0,"Progress", True,Null) AS S
FROM Query1;
Query1 could be a CROSSTAB instead of using IIf() expressions to emulate. CROSSTAB will return Null instead of 0 so would have to deal with that. Then adjust Query2 structure for different field names.
Anything else will probably need a VBA custom function.
I have an Access DB, along with tables and forms.
In one table I have customers and in a second table as a subdatasheet on the first table I have tags.
I have created a form which shows the customer list along with the subdatasheet which displays all the tags that a customer has.
I would like to filter based on a field of the main datasheet, and on the subdatasheet for a tag.
E.g. where customer_name = "Peter" and tag ="Neighbor"
I saw this code but when trying to use it fails.
Filter on Subdatasheet
When trying Set mainDS = Me.Controls(dataSheetName).Form where do I find the datasheetName?
I tried entering Form Name, Table Name, I searched in form properties but didn't manage to find a solution.
Based on your question it sounds like you are new to Access and you should review table normalization.
Everything starts with a normalized table structure. Unfortunately you are starting with the relatively difficult Many to Many Relationship. Each Customer can have many tags which is a One to Many Relationship, but there wouldn't be much point to comparing customers unless they could have the same tags, which means each tag can have many customers as well. For example, create your tables with the corresponding primary and foreign keys and tell access about the relationhip by hitting the ribbon and selecting the relationships tool:
The raw data in the CustomersTags table is what you are interested in, but it is not userfriendly
----------------------------------------------------------------
| CustomerTagID | CustomerID | TagID |
----------------------------------------------------------------
| 1 | 1 | 1 |
----------------------------------------------------------------
| 2 | 3 | 1 |
----------------------------------------------------------------
| 3 | 2 | 3 |
----------------------------------------------------------------
| 4 | 2 | 4 |
----------------------------------------------------------------
| 5 | 2 | 5 |
----------------------------------------------------------------
| 6 | 3 | 1 |
----------------------------------------------------------------
| 7 | 2 | 1 |
----------------------------------------------------------------
| 8 | 3 | 5 |
----------------------------------------------------------------
| 9 | 2 | 2 |
This is why we use forms for entering and viewing the data. For speeds sake select CustomersTags and hit create table:
This is not user friendly so we don't show primary keys and replace (right-click and select change to) all the i'ds with user friendly combo-boxes. I also change the forms format to Data sheet.
I continue making the form prettier and add two unbound combo boxes to the header to filter the form with. You can do this with listboxes or checkboxes, or etc as well. For instance a multi-select list box so you can select multiple tags. In all cases you just set the forms filter
Option Compare Database
Option Explicit
'select the combobox afterupdate property to get these events
'you can use macro's if you want
'the exact code is very dependent on things like whether you have default values. I just show the most necessary case
Private Sub cmbCustomer_AfterUpdate()
If (IsNull(Me.cmbCustomer) Or IsNull(Me.cmbTag)) Then
'do nothing
Else
'filter the forms record source
Me.filter = "(CustomerID = " & Me.cmbCustomer & ") AND TagID = " & Me.cmbTag
Me.FilterOn = True
End If
End Sub
Private Sub cmbTag_AfterUpdate()
If (IsNull(Me.cmbCustomer) Or IsNull(Me.cmbTag)) Then
'do nothing
Else
'the filter is just the WHERE PART of an sql statement without the where
Me.filter = "(CustomerID = " & Me.cmbCustomer & ") AND TagID = " & Me.cmbTag
Me.FilterOn = True
End If
End Sub
Next, I switch the forms format to continuous forms and continue prettyifying because to my surprise the datasheet format was blocking setting the filter string.
Here is some guidance for making comboboxes, comboboxes are used for displaying userfriendly values instead of IDs. For instance instead of displaying the raw CustomerID we display the Customer_name but the value in the combobox is the CustomerID. The unbound combobox's value is the CustomerID corresponding to the user friendly Customer_Name the user selects. Whether the combobox is bound or unbound you set them up in the same way. Select a bunch of columns from some table or query then declare how many columns you are showing and their width. To hide a column set it's width to 0. The order of the columns determines the order of the numbers. I bound to the tables and both tables go ID then user friendly description so column-widths is 0,1
This example allows selecting impossible combinations of Customer and tag which will cause an error. One way to avoid this would be to set the rowsource of the alternate combobox when you choose a value on the first. For instance, when you pick a customer you restrict the tags which can be selected in the next combobox. This is cascading comboboxes:
Option Compare Database
Option Explicit
Private Sub cmbCustomer_AfterUpdate()
'it helps to use the query designer to get the sql right
Me.cmbTag.RowSource = "SELECT Tags.TagID, Tags.FriendlyDescription" & _
" FROM Tags INNER JOIN (Customers INNER JOIN CustomersTags ON Customers.CustomerID = CustomersTags.CustomerID)" & _
" ON Tags.TagID = CustomersTags.TagID WHERE (((CustomersTags.CustomerID)= " & Me.cmbCustomer & "))"
Me.cmbTag.Visible = True
End Sub
Private Sub cmbTag_AfterUpdate()
Me.filter = "(CustomerID = " & Me.cmbCustomer & ") AND TagID = " & Me.cmbTag
Me.FilterOn = True
Me.cmbCustomer.SetFocus
Me.cmbTag.Visible = False 'quick and dirty reset 'can't invis a focused control
Me.Refresh
End Sub
Each row in my dataset has an unique identifier. I want them to be ordered by my own custom order sequence. Here's an example:
I have my raw data:
ID Name
-------
1 Peter
2 John
3 Steve
And my order sequence, e.g. 3,1,2.
When I initialize the DataTable I want my entries to show up like this (according to my pre-computed order sequence):
ID Name
-------
3 Steve
1 Peter
2 John
Your code seems to work just fine. There were couple issues though.
RowReorder plugin requires order column in order to work correctly.
You need to handle reorder event row-reorder and change your URL hash accordingly.
Sorting on the top table needs to be disabled unless you want to handle order event and adjust URL hash accordingly.
See this jsFiddle for code and demonstration.
I'm a bit stuck with this...
I have items table:
id | name
1 | item 1
2 | item 2
3 | item 3
4 | item 4
and related items table:
id | item_id | related_item_id
2 | 1 | 2
3 | 1 | 4
so this means that item 1 is related to items 2 and 4.
Now I'm trying to display these in a list where related items follow always the main item they are related to:
item 1
item 2
item 4
item 3
Then I can visually show that these items 2 and 4 are related to item one and draw something like:
item 1
-- item 2
-- item 4
item 3
To be honest, haven't got any ideas myself. I quess I could query for items which are not related to any other item and get a list of "parent items" and then query relations separately in a script loop. This is not definately the sexiest solution...
I am assuming that this question is about ordering the items list, without duplicates. That is, a given item does not have more than one parent (which I ask in a comment).
If so, you can do this with a left outer join and cleverness in the order by.
select coalesce(r.related_item_id, i.id) as item_id
from items i left join
related r
on i.id = r.related_item_id
order by coalesce(r.item_id, i.id),
(r.related_item_id is null) desc;
The left outer join identifies parents because they will not have any rows that match. If so, the coalesce() finds them and uses the item id.
In my opinion , rather than implementing this logic in a query , you should move it to your actual code.
assuming that item_ids are sequential, you can find the largest number of item_id, then in a loop
you can find related_item_id to each item_id and make a convenient data structure out of it.
This functionality comes under the category of hierarchical queries. In Oracle its handled by connect by clause not sure about mysql. But you can search "hierarchical queries mysql" to get the answer.
I created a table out of a CSV file which is produced by an external software.
Amongst the other fields, this table contains one field called "CustomID".
Each row on this table must be linked to a customer using the content of that field.
Every customer may have one or more set of customIDs at their own discretion, as long as each sequence starts with the same prefix.
So for example:
Customer 1 may use "cust1_n" and "cstm01_n" (where n is a number)
Customer 2 may use "customer2_n"
ImportedRows
PKID CustomID Description
---- --------------- --------------------------
1 cust1_001 Something
2 cust1_002 ...
3 cstm01_000001 ...
4 customer2_00001 ...
5 cstm01_000232 ...
..
Now I have created 2 support tables as follows:
Customers
PKID Name
---- --------------------
1 Customer 1
2 Customer 2
and
CustomIDs
PKID FKCustomerID SearchPattern
---- ------------ -------------
1 1 cust1_*
2 1 cstm01_*
3 2 customer2_*
What I need to achieve is the retrieval of all rows for a given customer using all the LIKE conditions found on the CustomIDs tables for that customer.
I have failed miserably so far.
Any clues, please?
Thanks in advance.
Silver.
To use LIKE you must replace the * with % in the pattern. Different dbms use different functions for string manipulation. Let's assume there is a REPLACE function available:
SELECT ir.*
FROM ImportedRows ir
JOIN CustomIDs c ON ir.CustomID LIKE REPLACE(c.SearchPattern, '*', '%')
WHERE c.FKCustomerID = 1;