I have a Form that looks like this:
Section | Length | Number
Dropdown of sections | Integer | Integer
Then I have a SQL that looks like this
Section (List of sections) | Weight (Weight of section) | Cost (Cost of section)
The user will chose the section from the dropdown, enter the number of the section required and the length of the section. The user will then click a button to add the data to a table underneath the form.
On click I need the chosen section's length multiplied by number then multiplied by weight, and chosen section's length multiplied by number and then by cost. Which will then be displayed in a table like this
Section | Total Length | Weight | Cost
152x152x25 | 5000 | 25 | 600
It must be able to add quite a few entries to the table.
Sadly, I'm a designer and not a programmer, so if I could get some help, I would really appreciate it.
edit
The answers I used (152x152x25|5000|25|600) are just an example.
I'm going to use a normal Linux server to deliver an HTML page containing the form and the table. There will then be a "Print" to print the table and "Send" to email the table. I plan on populating the SQL database myself.
Related
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 feel like I'm missing something very obvious, but searching hasn't given me a solution and I hope someone can help.
I am working on a simple chart. X axis is the date (day), Y axis is a simple number (1 to 100).
I have totals, for 3 different sites, per day. I need a line for each site on the chart.
Day | Site | Value
---------+--------+-------
Monday | site X | 30
Monday | site Y | 45
Monday | site Z | 20
Tuesday | site X | 35
Tuesday | site Y | 26
Tuesday | site Z | 12
and so on..
There is only 1 total value per day, per site.
I am trying to create 3 lines on the chart, one for each site but I can't figure out how to filter on the series level. (I'm working on a very large date range, so lines work better visually rather than doing a series group of bar charts, or even stacked bar charts)
I originally tried the multiple dataset work around (using an expression and something like
sum(field!total.value, "site X")
but that didn't work (it showed only a straight line, the first value I think) . Now, I have one dataset, but I can't find a way to filter series so they only show for one site.
I also tried this IIF
=iif(Fields!site.Value = "site X", fields!total.value,0)
but that gives a weird looking line.
I can't believe this is not possible in a chart in SSRS, I mean, it's pretty basic, so I must be missing something.
Thank you for your help.
You need to set up a chart as follows
The Values are the actual numbers you are attempting to chart
The Category groups as set up here are the individual dates.
The Series Groups are your Sites
At this point I then set the Horizontal Axis to be in Scalar/Dates format so the designer looks as follows
When you run this report using an adaptation of the (brief) dataset example above you get the following
Is it possible to show data from database in SSRS footer?
I tried but the only option present is to show first record from dataset. But I want to show all records (I just need to show one column) one by one on each page.
Is it possible?
Based on your comment I believe this link Display on Page Footer is what you are looking for.
I tried this and it works on Page Footer.
One way to do this is by making your report a list of subreports.
Make a new report with a List item and a dataset that gets a set of all the departments you are going to get. Consider this to be your "List" report.
Populate the list with the dataset. Put a page break between List item members.
Make another report (or modify your existing one so) that is designed to be a single-page report about a single department, so #department will be one of the parameters. It contains all the data you want on each page of your report, including the footer with the Department name, which it gets from the department parameter, so it doesn't need to get it from a dataset. Consider this your "Base" report.
Going back to your List report, put a sub-report in your List item, point the sub-report to your Base report, and populate the department parameter with the value from the dataset that is populating the List.
Yes, it is possible using the "Lookup" aggregate function.
Assume, your report has a dataset named "Department_DataSet" which contains all the department's data plus one additional column e.g. PageNum, that contains an integer sequence starting from 1, giving you, basically, a sequence of the report page numbers:
PageNum | DepartmentName | Address | etc.
--------+------------------+------------+-----
1 | Department 1 | ... | ...
2 | Department 2 | ... | ...
...
N | Department N | ... | ...
Now, add a Textbox into the footer and assign the following expression to it:
=Lookup(Globals!PageNumber, Fields!PageNum.Value, Fields!DepartmentName.Value, "Department_DataSet")
and it will show the department name as required, but please ensure that the page numbers go in the same order as the departments in your detail report.
I have a pretty large form that consists of radio buttons/checkboxes as well as text inputs. Due to the nature of checkboxes, if they post the form without checking it, it isn't sent in the POST data. Which leaves me a bit stuck with how to handle it.
I originally started my database with the standard 'column for each field'. For example:
id | userid | firstname | lastname | middlename | phonenumber | mobilenumber |
That quickly changed when I ended up having upwards of 30 columns. This form is huge. I've decided I'll use an 'EAV schema' to give my table only 4 rows. It now looks like so:
id | userid | name | value
---+--------+-----------+------
1 | 1 | firstname | steve
---+--------+-----------+------
2 | 1 | lastname | blah
This seems like a nicer approach.
So my question is, how should I handle the database when I'm not entirely sure what's going in it? If I have 20 checkboxes (each with their own name), should I manually check if each was submitted and set a 'null' value if not?
Should I empty all the rows from the table for the user's ID and replace it with all the new data?
What's an efficient way of doing this?
EAV is an anti-pattern in this case. You will end up with very convoluted logic just to retrieve a single set of data.
Your first approach is more maintainable and understandable to others.
When it comes to a boolean value, such as a checkbox value, I would use a bit/boolean field in the database, where a check mark would be a true and the fact that you didn't get it posted back would become a false.
The same thing stands for the EAV schema - keep them all in the DB, just mark the value as true or false, depending on what was posted.
You should parse your input first, and determine proper values for each item. Then you take the data and put in the database.
The code should not rely on the existance of fields in the form to determine what fields to put in the database. A form can easily be manipulated, so it could be used to change any field in the table, not just the ones corresponding to the fields that you put in the form.
The EAV schema is good if you have plenty of similar fields, or a dynamic set of fields. Perhaps you should store the text data in the regular way and the values from the checkboxes in a separate table.
Perhaps a little off topic, but to work around the checkbox functionality, add a hidden input with the same name before the checkbox and value - zero (or a value that means 'not set'):
<input type="hidden" name="blah" value="0">
<input type="checkbox" name="blah" value="1">
in that way, if the checkbox isn't checked, you'll still get a value of 0 in your post - but if it is checked, you will get 1, because the last field of the same name is POST'ed.
I have a report that shows financial data by year along with a few other bits of static data:
every time I try to put in a Column group, it does either above or below the static data:
FiscalYear
StaticData1 | StaticData2 | StaticData3 | StaticData4
Or:
StaticData1 | StaticData2 | StaticData3 | StaticData4
FiscalYear
What I want is that I get the static data and then the dynamic data (which may be 1 or 20 additional columns) right beside it with the corresponding data below
How do I get the report to look something like:
StaticData1 | StaticData2 | StaticData3 | StaticData4 | FiscalYear | FiscalYear+1 ...
Thanks much!
See Dynamic Grouping to learn how to make your matrix groupings dynamic based on report parameters.
Wait a second. I think that doesn't answer your question.
It sounds like you're asking how to make more columns appear to the right of your static data at the same level of grouping. The only thing I can recommend is to modify your recordset to return a row for each final matrix cell. This usually involves a partial unpivot.
You have something like:
Row1 Static1 Static2 Year
Row1 Static1 Static2 Year
instead, you need this:
Row1 'Static1' Static1Value
Row1 'Static2' Static1Value
Row1 'Year' YearValue
Row2 'Static1' Static1Value
Row2 'Static2 Static2Value
Row2 'Year' YearValue
I hope that makes sense. I don't have a lot of time to go into much detail.
One other thing that might help you is to experiment with dropping a Rectangle into one of the matrix detail cells. Once you have that, you can drop as many text boxes into the Rectangle as you want and position them as desired. This is one of the ways to get extra values to show even though you only want one grouping level.