ms access db order by month asc issue - ms-access

In my database i have month name as january, february, march like that.
I represent field name is text. When i execute the select query with order by month field month, it will provide the output as february, january like that.
I know it is clear by the FORMAT or db field representation. Though i am new to the ms access so i don't know the correct format for this. Please help me.

You will have to create your own custom function in a module that cnverts the value for you.
Something like
Public Function StrToMonth(strIn As String) As Integer
Dim arrMonth(12) As Variant
Dim i As Integer
arrMonth(0) = "January"
arrMonth(1) = "February"
arrMonth(2) = "March"
arrMonth(3) = "April"
arrMonth(4) = "May"
arrMonth(5) = "June"
arrMonth(6) = "July"
arrMonth(7) = "August"
arrMonth(8) = "September"
arrMonth(9) = "October"
arrMonth(10) = "November"
arrMonth(11) = "December"
For i = 0 To UBound(arrMonth) - 1
If strIn = arrMonth(i) Then
StrToMonth = i + 1
Exit Function
End If
Next i
End Function
And then you can use it in your queries like
SELECT Table1.MonthVal
FROM Table1
ORDER BY StrToMonth([MonthVal]);

Add an additional column to the table(s) with month names that have the month-number-in-year, or much better, don't store months as strings, instead store them as dates e.g. 1 August 2010, which will make this problem considerably easier to solve.

Store the months as integers as currently your rows are returned using alpabetic sorting (how should database know that these strings there are months?): April, August, February, January, March...

You can convert the month to a date for the purpose of sorting:
SELECT MonthName
FROM SomeTable
ORDER BY CDate("1/" & [MonthName] & "/2010");

If you've decided it's inappropriate to store the months as actual dates (and it certainly could be -- I'm not criticizing that decision), you want to maximize performance by storing your data in a format that is most efficient.
That is most likely storing the month as an integer.
For display purposes, say in reports, or on a form, you can display the month name using format. It's a little tricky, as there's no direct conversion (where "MonthField" refers to the field where you're storing the month integer):
Format(DateSerial(Year(Date()), MonthField, 1), "mmmm")
An alternative would be to have a table that maps a month integer to the month name, but that adds a join, and if the field can be blank, you'd have to have an outer join, and that's much more expensive performance-wise than an inner join.
Keep in mind that you'd use the Format() statement only in the presentation layer, i.e., as the controlsource of a control on a form or report. On forms you'd likely use a 2-column combo box for this purpose, so the user would see the month name, but the value stored would actually be the month integer. In that case, a table might make sense, but I'm not certain that it would have any real advantage over just typing in a value list -- it's not like this is volatile data, i.e., data that may need to be edited (which is the main reason you'd use a table in place of a value list)!
EDIT:
As #HansUp has pointed out, there's a MonthName() function in VBA (I didn't know it existed!), so that makes all the above way more complicated than it needs to be -- you could use that in the presentation layer without a need for a table or for the complicated Format() statement.

Related

SSRS select parameter month and change par. first and last day of this month

i need to create parameter list of months and then (after select) recalculate two others paramateres in date format ([first day] and [last day]) of this month, can you please help me?
You are querying a database server to generate the list of months, although there's no need to do that. I suggest to rather create a list of months in the report and let the report calculate the month's names, so the language depends on the Language setting of the report (which can be the language configured in the user's browser).
For example, to calculate the Label for the Value 1, use an expression like =MonthName(1).
The Parameters FirstDay and LastDay (or just the values whenever you need them) can be calculated using these expressions:
FirstDay: =DateSerial(Today.Year, Parameters!Month.Value, 1)
LastDay: =DateSerial(Today.Year, Parameters!Month.Value, 1).AddMonths(1).AddDays(-1)

Error in Expression used for Control Source in an Access Form

I actually have two questions.
I'm a beginner user of Access, still trying to get a good understanding of the software. I'm trying to create a database for a library (School project) with a borrowing out system. I have two fields in a table called DueDate and DateHired. The DueDate functions on the expression =Now()+28 and the DateHired function on the expression =Now(). Basically making the due date 4 weeks ahead of when the book was hired. My first question is quite simple; if I were to input a record today, would the two DueDate/DateHired fields remain the same date and time by tomorrow? Or would they update to the Now() of tomorrow?
My second question is something regarding an expression. I'm trying to make an Overdue checkbox. The premise is that if Now()>DateDue then the Checkbox will be 'Yes'. My current code in the ControlSource part is this:
=CBool([DateDue]
However, the checkbox simply displays '#Error' and not Yes/No. I'm also concerned that if the answer to the first question was '=Now() stays the same after the record is added and doesn't update' that would also mean the Overdue function would not really work unless you were inputting the record after the due date. Which would make no sense. Any suggestions?
Cheers.
This is relation to your second question. You can ask a separate question for the first part.
=CBool([DateDue]
What you are trying to do here, is convert a Date data type to a Boolean (you're missing the closing parentheses by the way) which is impossible.
What you should be doing is check if the due date is less than today and return the appropriate True/False value.
IIf([DueDate] < Date(), True, False)
Which means:
IIf("Is due date in the past?", "Yes, it's overdue", "No, it's not overdue")
You can read more about the IIf function here.
Indeed as a beginner, make it a habit to use the date functions. Later you can turn to "smarter" methods which, by the way, often aren't that smart.
1.
If you store a date, it remains unchanged in the table. And don't use Now unless you specifically need the hours too:
DateDue = DateAdd("d", 28, DateHired)
or in a query - using the designer:
DateDue: DateAdd("d",28,[DateHired])
or as a ControlSource for a textbox on your form:
=DateAdd("d",28,[DateHired])
2.
You can use DateDiff for this:
Due = DateDiff("d", DateHired, Date) > 28
or in a query - using the designer:
Due: DateDiff("d",[DateHired],Date()) > 28
or as a ControlSource for a textbox on your form:
=DateDiff("d",[DateHired],Date()) > 28
and set the Format property of the textbox to, say, Yes/No or something else meaningful for your users.

Dynamically change column names as week number on every weekly run

I want to build a SSRS report that has column as week numbers - 8 weeks for 8 columns starting with current. This report is run every week and current week number is set then. So both column names and their values should change .Is it possible to build something like this in SSRS?
I tried doing this with a dynamic SQL based stored proc in dataset. However for every run I don't even see the columns values updating dynamically
Here's an example :
Also I am trying to avoid these week numbers as row values and then using matrices
My stored proc looks something like this
declare #n tinyint = datepart(wk, getdate())
declare #n1 tinyint = (#n+1), #n2 tinyint =(#n+2), #n3 tinyint =(#n+3), #n4 tinyint =(#n+4), #n5 tinyint =(#n+5), #n6 tinyint =(#n+6)
exec ('Select b.sku, b.['+#n+'], b.['+#n1+'], b.['+#n2+'], b.['+#n3+'], b.['+#n4+'], b.['+#n5+']...
Will appreciate any help in this direction.. many thanks!
When working with SSRS it's generally best to avoid dynamic SQL and pivoting the data in the SQL. Use the SQL to get the raw data you need and then let SSRS do the pivoting and aggregation. This way you take advantage of what they each do best. I know you said you want to avoid matrices, but it is the best way to make the report dynamic.
So you should either return all the data in one dataset and use filters on your matrices OR write two queries and have each one populate a matrix. BTW a matrix is just a table with a column group added, so don't be intimidated by them.
There are 2 ways to do this with a standard tablix.
Calculate the column headers as expressions using concatenation of Wk and some date math to find the correct week number and return the same sort of thing from your query (e.g. columns are current_week, week_minus_1, week_minus_2...)
Return the column headers as additional columns in your query that are the same value for every row (e.g. ColHeader0, ColHeader1...). Your data columns would still be relative weeks (e.g. ValueWeek0, ValueWeek1...). In your report the column header would have an expression like =First(Fields!ColHeader0.Value). This is a more flexible approach since it lets you pick 8 historical weeks instead of only the last 8 weeks if you add a parameter.
EDIT - Clarifications
The reason that you get the blank column Wk48 is approximately that you have created your report looking for that column that won't be there the next time. SSRS looks for exact columns. You should you use relative column names for either of the options I have specified:
exec ('Select b.sku, b.['+#n+'] as Wk0, b.['+#n1+'] as Wk1, b.['+#n2+'] as Wk2, b.['+#n3+'] as Wk3, b.['+#n4+'] as Wk4, b.['+#n5+'] as Wk5...
This will allow you to populate the aliased Wk0 column with the appropriate current week data and still make sure that it can be consistently referenced as the base week by SSRS.
To change the column headers you can:
Independently calculate the week numbers in SSRS in the column header expressions: ="Wk" + CStr(<correct week calculation>).
Return the column headers in the result set and access them in the column header expression:
exec ('Select b.sku, b.['+#n+'] as Wk0, b.['+#n1+'] as Wk1, b.['+#n2+'] as Wk2, b.['+#n3+'] as Wk3, b.['+#n4+'] as Wk4, b.['+#n5+'] as Wk5..., ''Wk'''+#n+' as ColHeader0, ''Wk'''+#n1+' as ColHeader1...
and reference the returned column headers from the SSRS column header expression as =First(Fields!ColHeader0.Value).
Here's a solution that worked for me:
Create parameters (say CurrWk, CurrWk1) ,set as hidden and store 'Default value' and 'Available value' equals to current week number (datepart(wk, now()) and any subsequent week by doing a +1, +2, +3.. etc.
Write a query expression . Click onto fx beside dataset query space and write the select query for your program embedding parameter values in the expression window. For eg ="Select SKU, [" & Parameter!CurrWk.Value & "] as Wk1,
[" & Parameter!CurrWk.Value & "] as Wk1 from Sales_Table"
Before passing this query as a 'command text expression' please ensure this query is working in sql ssms.
Save the expression. Now find 'Fields' tab on the left hand side panel.You need to map the fields manually from the query here. If this is not done, there is a very high chance you seean empty field list and wont be able to access them at all. This may be because ssrs do not store query metadata directly from expressions.
You can avoid part of the issue by having atleast the static fields , for example here SKU listed in the 'Fields' list by first running a sql query with static field(select SKU from Sales_Table ). You can then go back to update dataset- change query to expression and embed the parameterized field names.
Map field names. In this example I chose 'Query Type' fields and set Field names as SKU, CurrentWeek, NextWeek and mapped to source SKU, Wk and Wk1 respectively.
Click on 'Refresh Fields' at the bottom. Now you have a dataset with the complete field list. Use these in charts, tables . Run it every week and note the numbers changing as expected.
In case you are using this dataset in a table, make sure you set headers with Labels of Parameters (for eg here I did =Parameters!CurrWk.Label for col with current week data)
That's it!

Classic ASP, DATE difference between IIS6 and IIS8

I am helping to migrate a classic asp website (front end) and ms access database (back end) from a Windows 2003 IIS6 server to a Windows 2012 IIS 8.5 server. I am having a problem with this query in particular;
sqlquery1 = "Select RentalNum, CarID, RentalStatus, StartDate, EndDate from table where CDate(EndDate) <= CDate('"&Date()&"') order by CDate(EndDate) desc"
On the existing system all is ok. On the new system the returned results are not <= "todays date". The results show some dates before today and some after. The database date fields are just "text" (I didn't set it up) and whilst my initial thoughts were to change the schema to proper dates, I would like to understand the problem, particularly as there are many of parts of the system using similar queries using date() and CDate. Are there underlying dates differences between IIS servers? I have looked at browser locality and all is ok there.
Any pointers?
Examine this expression used in your query:
CDate('"&Date()&"')
The Date() function returns the system date as a Date/Time value. But then that expression adds quotes before and after the Date/Time value, which transforms it to a string value. And then CDate() takes that string and transforms it back to a Date/Time value again.
Hopefully that description convinces you those manipulations are at best wasted effort. However if the two servers have different date format settings, the dates resulting from that full CDate() expression could be different.
I'm not positive that is the source of your problem, but you can easily eliminate the possibility. The Access db engine supports the Date() function, so you can use it directly without first transforming it to a string and then back into a Date/Time value.
sqlquery1 = "Select RentalNum, CarID, RentalStatus, StartDate, EndDate " & _
"from [table] where CDate(EndDate) <= Date() order by CDate(EndDate) desc"
If that change does not solve the problem, next examine those EndDate text values and make sure they're interpreted as the date you expect:
SELECT EndDate, CDate(EndDate) AS EndDate_as_date
FROM [table];
You mentioned your "initial thoughts were to change the schema to proper dates". I think that is the best way to go because developement based on dates as Date/Time is saner than with dates as strings.

How to set the year part of a field using a query

Evening,
I have created a query that is suppose to change ONLY the year part of a Date/Time field to 1900 when a person is 89 years or older. The query that follows compiles fine but when run it complains about a Type Conversion failure and removes the entire value from the records affected.
The query:
UPDATE tblTestForDOB
SET tblTestForDOB.[PT_BirthDate] = DateValue( (day([PT_BirthDate])/month([PT_BirthDate])/1900) )
WHERE Year(tblTestForDOB.[PT_BirthDate]) <= Year(Date())-"89";
According to the MS Help (F1 over the function):
The required date argument is normally a string expression representing a date from January 1, 100 through December 31, 9999. However, date can also be any expression that can represent a date, a time, or both a date and time, in that range.
Is that not what I'm doing? I also tried placing the " " & before the values inside the DateValue function and that did the same thing
(to ensure that it was a string that was passed)
So how do I go about it? Should I use CDate to convert the value to a Date and then proceed that way? If so what is the correct syntax for this?
Thanks
P.S The field is of Short Date format. Also note that I don't want to take the long way around and use VBA for the whole thing as that would involve opening record sets and so on...
It appears you're trying to give DateValue a string, but that's not what's happening. There may be more going on that I don't understand, so I'll just show you an Immediate window session which may contain something you can build on.
PT_BirthDate = #1923-6-1#
? PT_BirthDate
6/1/1923
? DateDiff("yyyy", PT_BirthDate, Date())
90
' this throws error #13: Type mismatch ...
? DateValue( (day([PT_BirthDate])/month([PT_BirthDate])/1900) )
' it will work when you give DateValue a string ...
? DateValue("1900-" & Month(PT_BirthDate) & "-" & Day(PT_BirthDate))
6/1/1900
' or consider DateSerial instead ...
? DateSerial(1900, Month(PT_BirthDate), Day(PT_BirthDate))
6/1/1900