I need to handle the data from a CSV list. I need to import this list, but for that, I need to join the data, separated by commas.
Currently the list looks something like this:
COMPANY;CITY;COUNTRY
Comp1;curitiba;brazil
Comp2;curitiba;brazil
Comp3;detroit;usa
Comp4;detroit;usa
What I need is to group the values, separator by comma, according to the city, exactly as follows:
COMPANY;CITY;COUNTRY
Comp1,Comp2;curitiba,curitiba;brazil,brazil
Comp3,Comp4;detroit,detroit;usa,usa
The list has thousands of lines, which makes it impossible to do it manually.
Would anyone know a way to do this with some tool?
You could use some SQL aggregation function.
In sqlite in example, starting from this kind of table, named "input"
+---+---+---+
| a | b | c |
+---+---+---+
| 2 | 3 | 3 |
| 1 | 3 | 4 |
| 2 | 5 | 7 |
+---+---+---+
and running
SELECT
a,GROUP_CONCAT(b) b,GROUP_CONCAT(c) c
FROM
input
group by a
you will have
+---+-----+-----+
| a | b | c |
+---+-----+-----+
| 1 | 3 | 4 |
| 2 | 3,5 | 3,7 |
+---+-----+-----+
The GROUP_CONCAT function is in a lot of db systems (not only sqlite).
Using Miller (https://github.com/johnkerl/miller) is very easy.
Running
mlr --csv --fs ";" nest --implode --values --across-records --nested-fs "," -f COMPANY input.csv
you will have
COMPANY;CITY;COUNTRY
Comp1,Comp2;curitiba;brazil
Comp3,Comp4;detroit;usa
Some notes:
--fs ";", to set the field separator of the file;
nest --implode --values --across-records, to set the implode nesting across the records;
--nested-fs ",", to set the nested field separator;
-f COMPANY, to set the field to implode.
If I'm understanding you correctly and you just want every two rows to be combined into a single row, then the following will get you where you need to go. Otherwise, it should be enough to introduce you to Power Query and you can adjust from what this is to what you need.
From within a new workbook in Excel...
Do Data - New Query - From File - From CSV from the Microsoft Excel ribbon. This will open up the "Power Query Editor"
Confirm/adjust to make sure it's importing your starting format correctly.
Rename the query you create to "RawImport". (Look for the "Name" property on the right sidebar.)
Create a new query that starts with the current one by, from the ribbon (in the Power Query editor), clicking Home - Manage - Reference
Click View and ensure that "Formula Bar" in the ribbon is checked.
Change the name of this query to "RawImportEvenOdd"
Click Add Column - Index Column from the ribbon. This should create a new "Index" column that starts with 0 and increments by 1.
Click Add Column - Custom Column from the ribbon. In the dialog box, give it a name of "IsEvenRowNum", and a formula of Number.Mod([Index], 2) = 0
Click the little "ABC 123" icon in the left edge of your new "IsEvenRowNum" column's title. Change it to a type of "True/False". This isn't necessary, but trust me and start your habit of strongly typing your data today. It will save you from yourself one day.
Create a new query that will be only the even rows by clicking Home - Manage - Reference
Rename this third query to "RawImportEvenOnly"
Click on the little filter button on the right edge of the "IsEvenRowNum" and filter your query to only show rows where IsEvenRowNum is true
Click Add Column - Custom Column and in the dialog box, name it "NewRowNum" with a formula of [Index]/2
Click Home - Choose Columns and change it so only COMPANY, CITY, COUNTRY, and NewRowNum are selected.
Double-click on the "COMPANY" column title and add "_E" to the end (renaming it to "COMPANY_E")
Repeat the same for CITY and COUNTRY
Create a new query that will be only the odd rows by clicking Home - Manage - Duplicate (note: Duplicate, not Reference)
Change the query name to "RawImportOddOnly"
Click on the Filtered Rows step in the right side-bar and then edit the displayed formula in the formula bar to change true to false
Click on the next step, "Added Column", and then edit the formula from = Table.AddColumn(#"Filtered Rows", "NewRowNum", each [Index]/2) to = Table.AddColumn(#"Filtered Rows", "NewRowNum", each ([Index]-1)/2)
In the last step, "Renamed Columns", change it so that it appends "_O" instead of "_E" to COMPANY, CITY, and COUNTRY.
If the left side-bar hasn't already expanded for you, you can expand it to see the queries you've made so far. Click the "RawImportEvenOnly" query to go back to editing it.
Click Home - Manage - Reference to start making your final query.
Change the name to whatever you like.
Click Home - Merge Queries and, in the dialog box,
Click on the "NewRowNum" column title to highlight it.
Change the dropdown box for the second table to be "RawImportOddOnly"
Click on the "NewRowNum" column title on this second table to highlight it.
Click Okay.
Okay, so now the value of our new column for any given row is a subtable of the corresponding row from RawImportOddOnly, and we need to expand it. Instead of a filter button, the button the right edge of the new "RawImportOnly" column is an expand button. Click it. In the dialog box, make sure only COMPANY_O, CITY_O, and COUNTRY_O are selected, deselect "Use original column name as prefix" at the bottom of the dialog box, then click "Ok"
Click Add Column - Custom Column, name it "COMPANY" with a formula of [COMPANY_E]&","&[COMPANY_O]
Click Add Column - Custom Column, name it "CITY" with a formula of [CITY_E]&","&[CITY_O]
Click Add Column - Custom Column, name it "COUNTRY" with a formula of [COUNTRY_E]&","&[COUNTRY_O]
Click Home - Choose Columns and change the dialog box so only COMPANY, CITY, AND COUNTRY are selected.
In the Home ribbon, click, the tiny little down-arrow in the "Close & Load" button and choose "Close & Load To", and choose "Only Create Connection" and click Ok.
Now you're back at Excel and nothing's happened (except for your new queries appearing in a side-bar)! This is because we didn't load anything into Excel, we only made query definitions. We did this because we just created a whole lot of queries and we didn't want to store the results of each and every one; we only want the last one! In the side-bar, right click on the last query you created, click "Load to..." and load it to a new worksheet. This will do all of the work we've set up, from the beginning... which is great because if you realize you want to change any part of how this was made, go ahead, then refresh! Maybe I misunderstood you and you needed to sort it first? Maybe you've changed your mind and want to separate by slashes instead of commas? Change the queries and refresh the resulting table, and your new set of steps are done.
Not described is how to get this into a the semi-colon delimited file you're looking for, but I assume you can take it from there?
I am designing a small hospital database.
The doctor has given me a list of various values that can apply to a text field.
for Example a list of 20 diseases out of which more than one can apply in the diagnosis text box.
there 50+ such lists for various fields in the whole database.
Ms Access does not let Multiple value List be edited so what i have designed is as follows.
First the doctor selects a value from the combo box drop down list and to it more can be added as LimitToList is set to YES. Then an "ADD" Button near the list is linked which concats the new value to the older value of the text box using a piece of VBA code onClick.
Dim add As String
Dim past As String
past = [Forms]![Exam]![diagnosis]
add = [Forms]![Exam]![diseases list]
[Forms]![Exam]![diagnosis] = past + add + ", "
Me.Refresh
Here the list values are stored in the form only.
My question is , is this the best practice which can be used in the scenario?
Also, when i link the list data to a table as there are varying number of records in each row( for different fields), white spaces also show up in the combo box list.
I'd create 3 tables
1 "Diagnosis"
2 "Disease"
3 a junction Table "DiagnosisXDisease"
Schema
1
DiagnosisID | Diagnosis
2
DiseaseID | Disease
3
DiagnosisID | DiseaseID
You can then have the user select one from the first combo and have a continuous form below where you add a record for each related value.
Where you have a combo box to choose from the list
This way you can add as many as you need.
http://www.599cd.com/tips/access/form-subform/
http://www.599cd.com/tips/access/combo-box-select-customer/
http://www.599cd.com/tips/access/relational-tables/
Short form of the question:
How can I set a filter for the form which is used by the "List Items Edit Form" property of a ComboBox?
Long description of the environment:
In my database, there is a growing number of structurally similar values which describe something. I collated all of these in one table named ComboTexts, and added a second table ComboTextTypes to customize the field names on the user side. Example:
ComboTexts table:
ID s1 s2 s3 TypeID
1 1 First Floor Ground Floor 2
2 2 Second Floor Null 2
3 AOX DIN 1485 determination of organic components 3
ComboTextTypes table:
ID formtitle ch1 ch2 ch3
2 Floor Floor Number Floor Name Alternate Name
3 Process Process name Standard Description
In order to edit entries in ComboTexts, I provide two forms: The form CoreData displays the list of formtitles from ComboTextTypes and an "edit" button. When the user selects a fomtitle and clicks "edit", the form EditComboTexts is called with a filter for TypeID set. EditComboTexts extracts the TypeID from its filter and modifies itself with the information from ComboTextTypes.
So far there exist 14 ComboTextTypes in the database, and that number is growing. I simply didn't want to have 14 or more tables and forms, which basically all do the exact same thing. Instead I just have two tables and forms, although a little more complicated ones.
The above mechanic is all set up and works fine.
Description of the problem:
The users want to be able to modify the 14th ComboTextType from inside the combobox. The detour through CoreData is three clicks too many, they know that ComboBoxes can offer an edit button for their value list, and want to use it at that point.
Access offers the "List Items Edit Form" for this purpose. When I enter the EditComboTexts form there, it's working in principle, but (of course) the filter is wrong.
How can I set a filter for that form?
You can filter the rowsource using SQL and simply change the rowsource value of the combo box
Me.Combo0.RowSource = "SELECT myfield FROM Table2 WHERE Table2.myfilter = 'value' ; "
I am trying to filter records from a combobox, if I select Cape Town only Cape Town records must show in the subform but if I select Durban only Durban records must display in the subform. I dont get any errors but if I Select Cape Town only Cape Town records shows and as soon as I select Durban the the Cape Town records still display it doesn change to show the Durban records in the subform. Heres my code below any help will be much appreciated Thanks
If Me.Combo0.Value Then
strFilters = "Sites = 'Cape Town'"
DoCmd.OpenForm "Home"
Forms!Home![Plant Transaction subform].Form.Filter = strFilters
Forms!Home![Plant Transaction subform].Form.FilterOn = True
ElseIf Me.Combo0.Value Then
strFilters = "Sites = 'Durban'"
DoCmd.OpenForm "Home"
Forms!Home![Plant Transaction subform].Form.Filter = strFilters
Forms!Home![Plant Transaction subform].Form.FilterOn = True
End If
As long as your tables are set up right you should be able to do this with little / no coding at all.
Lets create a table called destinations and put 3 fields in: Unique ID, Townname and Area: example:
ID | TownName | Areas
CT | CapeTown | PlaceWithinCapetown
CT | CapeTown | AnotherPlace
D | Durban | PlaceHereAswell
so on and so on.
Lets assume you have 2 elements on your form. A Combobox and a Listbox.
ComboBox - List of Towns
ListBox - List of Areas Within Town.
Lets say the combobox is called cboTowns and the ListBox is called lstAreas
Click on the combobox and in the Row Source place your query, Something like:
SELECT DISTINCT destinations.ID, destinations.TownName FROM destinations;
Here i have asked for the Unique ID and Town name and set my bound column to 2 (So Only The Town Name Shows when user selected one), Now your combobox is populated with the towns, You will note the towns are listed more than once. You need to change the property's of your query to allow Unique values only Go to Row Source, Click on 3 dots this take's you to query builder select a blank area and on the right find the setting Unique Values set this to Yes and the combobox is complete.
Now i have the list of Towns and the Unique ID we can get the listbox to start working. Before you move on if you List all of your information all in 1 table as detailed above it is easier to lookup the data. If its over 2 tables you will need to create a relationship in Access. before moving on.
Once done go to the list box and again in your row source you want to put something like:
SELECT DISTINCT destinations.ID, destinations.Areas FROM destinations WHERE (((destinations.ID)=[Forms]![FormName]![cboTowns])) ORDER BY destinations.Areas;
So here i told it to look for Unique ID that's been set via combobox and then look for areas attached to that Unique ID.
Every time the user selects a an entry from the drop-down box the list box updates straight away. no other coding needed. If you have more information and need to display other things you can then use the DLookup function to populate any other fields you might have.
I will also say if you don't want to restructure what you already have looking at the code you supplied I noticed you are not requerying anything. You will need a Me.requery after end if in order to refresh the form. otherwise it will not update anything.
I've been assigned the task to design a temporary customer tracking system in MS Access 2007 (sheeeesh!). The tables and relationships have all been setup successfully. But I'm running into a minor problem while trying to design the data entry form for one table... Here's a bit of explanation first.
The screen contains 3 dropdown boxes (apart from other fields).
1st dropdown
The first dropdown (cboMarket) represents the Market lets users select between 2 options:
Domestic
International
Since the first dropdown contains only 2 items I didn't bother making a table for it. I added them as pre-defined list items.
2nd dropdown
Once the user makes a selection in this one, the second dropdown (cboLeadCategory) loads up a list of Lead Categories, namely, Fairs & Exhibitions, Agents, Press Ads, Online Ads etc. Different sets of lead categories are utilized for the 2 markets. Hence this box is dependent on the 1st one.
Structure of the bound table, named Lead_Cateogries for the 2nd combo is:
ID Autonumber
Lead_Type TEXT <- actually a list that takes up Domestic or International
Lead_Category_Name TEXT
3rd dropdown
And based on the choice of category in the 2nd one, the third one (cboLeadSource) is supposed to display a pre-defined set of lead sources belonging to the particular category.
Table is named Lead_Sources and the structure is:
ID Autonumber
Lead_Category NUMBER <- related to ID of Lead Categories table
Lead_Source TEXT
When I make the selection in the 1st dropdown, the AfterUpdate event of the combo is called, which instructs the 2nd dropdown to load contents:
Private Sub cboMarket_AfterUpdate()
Me![cboLead_Category].Requery
End Sub
The Row Source of the 2nd combo contains a query:
SELECT Lead_Categories.ID, Lead_Categories.Lead_Category_Name
FROM Lead_Categories
WHERE Lead_Categories.Lead_Type=[cboMarket]
ORDER BY Lead_Categories.Lead_Category_Name;
The AfterUpdate event of 2nd combo is:
Private Sub cboLeadCategory_AfterUpdate()
Me![cboLeadSource].Requery
End Sub
The Row Source of 3rd combo contains:
SELECT Leads_Sources.ID, Leads_Sources.Lead_Source
FROM Leads_Sources
WHERE [Lead_Sources].[Lead_Category]=[Lead_Categories].[ID]
ORDER BY Leads_Sources.Lead_Source;
Problem
When I select Market type from cboMarket, the 2nd combo cboLeadCategory loads up the appropriate Categories without a hitch.
But when I select a particular Category from it, instead of the 3rd combo loading the lead source names, a modal dialog is displayed asking me to Enter a Parameter.
alt text http://img163.imageshack.us/img163/184/enterparamprompt.png
When I enter anything into this prompt (valid or invalid data), I get yet another prompt:
alt text http://img52.imageshack.us/img52/8065/enterparamprompt2.png
Why is this happening? Why isn't the 3rd box loading the source names as desired. Can any one please shed some light on where I am going wrong?
Thanks,
m^e
===================================================
UPDATE
I found a glitch in the query for the 3rd combo.. It wasn't matching up with the value of the second combo. I fixed it and now the query stands at:
SELECT Leads_Sources.ID, Leads_Sources.Lead_Source
FROM Leads_Sources
WHERE (((Leads_Sources.Lead_Category)=[cboLead_Category]))
ORDER BY Leads_Sources.Lead_Source;
Those nasty Enter Param prompts are GONE!!! However, the 3rd combo still stubbornly refuses to load any values. Any ideas?
Never mind. Found the fix. The BoundColumn property of the second combo wasn't set to the correct column. Hence the selection values in it were incorrect and the 3rd combo wasn't able to refer to the linked table properly (with the correct index).
Job done :)
Thanks to all who may have taken time out to review the problem.