msaccess sort order - ms-access

I probably am missing something very simple here, but I cannot see it. MSAccess is sorting strangely, to test this I have created a simple one text field table and inserted these values:
BB0-01
BB001-0
BB0-01a
Now, according to little old me, since BB0-01 and BB0-01a have the first 6 characters in common, and BB001-0 already deviates at the 4th, the -01 and -01a should be sorted close to each other, something like:
BB0-01
BB0-01a
BB001-0
But they are not. The sorted order is as in the first list, with the -0 in between the -01 and -01a. Reverse sorting puts the -01a at position #1 but the -0 stays in between them. How can this be?

Looks like the sorting disregards -
Can't find anything in the MS Access doc that says anything about it though.

Related

Access Calculation not calculating consistently or correctly: "greater than" in IIF statement

I created a MS Access database for tracking some items at work. Users enter data which is then aggregated in queries (using count or sum) to calculate the actual value for each area, joined using UNION, then compared to goals for that area. I attempted to enter an IIF statement to conditionally calculate the percentage of [Act]/[Goal], leaving it zero if [Act] is blank or 1 if [Act] is greater than [Goal] so there is nothing over 100%. The issue is that it works most of the time, but other times fails with no obvious logic error or reason why that I can figure out.
Sometimes it can't tell that [Act] > [Goal] even though looking at it, it's obvious. The numbers are all integers, nothing crazy or formatting differences. The formula in [Met] is what I hope to achieve. I added the [TEST] field to trace back where it might not be working, which shows Access just isn't always returning the correct answer to [Act] > [Goal].
My Query:
What comes out (just the broken part):
As you can see, it works correctly for most rows, but then thinks 149 is less than 52, and 128 is less than 3. Because of this, it generates [Met] values over 100%.
Has anyone had this happen before or have any suggestions? I have tried using refresh, clicking in the cell to hit enter, everything I can think of.
I think that although your columns are Ints, they are being converted to strings in the variables (or at least one of the variables) Goal and Met.
If you look at the data, you'll see that if you compare them the results of Test are correct for a string comparison.
E.g. "3" > "128" (Because the first character has a higher char value).
In your query, try surrounding the variables with Val() when you are comparing them, as follows:
IIf(IsNull([Act]),0,IIf(Val([Act])>Val([Goal]),1,Round([Act]/[Goal],2)‌​))

Capitalize Just the last Letter in string - MS Access

I have a column in my access database table, I ran a query to make it proper case by using StrConv([MyColumn],3) but last two letters are state names and this query makes SOmeThing, soMethINg, NY to Something, Something, Ny,
I want the result as Something, Something, NY
Is there a another query I can run after to capitalize last letter?
You can use:
UcaseLast: Left([YourColumn], Len([YourColumn]) - 1) & UCase(Right([YourColumn], 1))
Well, most people would tell you to store your 'address', 'city', and 'state' as separate fields. Then you Proper Case each separately and concatenate them together. If you can do that... that is your best approach.
If this is a database or file that's been tossed at you and you can't make the field/table changes... it's still possible to get your desired results. However, you better make sure all strings end with your state code. Also make sure you don't have foreign addresses since Canadian (and other countries) use more that two letters for the province code at the end.
But if you are sure all records contain two letter state abbreviations, you can continue with the following:
MyColumnAdj: StrConv(Mid([MyColumn],1,len([MyColumn])-2),3) + StrConv(right([MyColumn],2),1)
This takes the midstring of your [MyColumn] from position 1 to the length of your [MyColumn] minus 2 (leaving off the state code) and it Proper Case's it all.
It then concatenates (using the plus sign) to a rightstring of [MyColumn] for a length of 2 and Upper Case's it.
Once again, this is dangerous if the field doesn't have the State Code consistently at the end of the string.
Best of luck. Hope this helps. :)

Use of a Previous aggregate function in a TablixCell error in one tablix, not in another

I have an SSRS report that works just fine with this code for checking the previous cell in a tablix:
=IIF(SUM(Fields!Transactions.Value) >
Previous(SUM(Fields!Transactions.Value),"matrix1_Month"), "Green", "Red")
This works in the report in the first tablix, matrix1, just fine.
I copied that tablix, used a different Different dataset, called it xForeignCardholders, and used this code:
=IIF(Fields!Transactions.Value >
Previous(Fields!Transactions.Value),"xForeignCardholders_Month", "Green", "Red")
It is the same except for the name of the tablix.
Now the report gives me the error
"Use of a Previous aggregate function in a TablixCell ..."
Why would it work in the first instance, and not in the second? The report is just one datacell, with no aggregation. In a previous version of this report, three different tablixes (tablii?) all used the same kind of code without error.
I can fix this in SQL, but it would really add a lot of complexity to something that should be really straightforward.
My situation while similar, is not quite identical - so may not be what you're running into, but I've gotten that exact error, and it was because my grouping had changed - that is, each grouping has a unique name, so if you're copying expressions from one table to another, you have to make sure you've updated the group name in your 'Previous' expression. I was using a field called "Year" in both tables, but it appears you can't repeat a group from one table in another. So when I copied my cell (and the expression therein), the destination grouping was "Year1" or "Year2" etc. The expression had to be updated accordingly.
In your case, make sure that the each expression has the right group name, in your example, "xForeignCardholders_Month". You may find that the group name is actually "xForeignCardholders_Month1" or something similar.
I also found that when I would copy/paste the <> from one cell to another, it drops most of the expression. You have to edit the original expression, copy it, and edit the expression in the new cell, and paste it. This only seems to happen when using a small report code script calculate YoY delta, and everything after "code.GetDeltaPercentage" was being dropped from my expression when I copied. Just something to look out for.
Update: I just discovered that sometimes, after a copy/paste of some cells, after verifying the expressions were exactly the same, I would still get this error. Delete the contents of the cells, choose the Sum(Field.value) from the selector icon in the cell, and then edit the expression on the adjacent cell and plug in my 'Previous' expression, and it would work. If there's a good reason for this behavior, it's beyond me. Seems like another VS Bug. :|
I'm self taught, so I may have some terminology wrong, but hopefully that gets the idea across anyway.
I think the problem is that in the first instance you use an agregate function, whien in the second you use the value itself, without the aggregation, compare:
IIF(SUM(Fields!Transactions.Value) > Previous(SUM(Fields!Transactions.Value),"matrix1_Month"), "Green", "Red")
and
=IIF(Fields!Transactions.Value > Previous(Fields!Transactions.Value), "xForeignCardholders_Month", "Green", "Red")
Best regards,
~Alexey

How can I test and handle a #Func! error from within a query?

I have an Access query that has a some what complex field on it. Basically, I'm searching for a certain value, based on other derived criteria. The function either works, or it gives a #Func! error. There are a few reasons why I may get an error. That is fine, because in those cases I want to return Null.
How can I test and handle a #Func! error from within a query? Also, I tried to wrap the expression in an IsError() method, and handle that case. That still didn't work.
If, for example, you are using Instr with a field that may or may not be null, and that is causing the problem, you can either select only those fields that are not null, or concatenate an empty string with the field.
SELECT Mid(AField & "",Instr(Afield & "","x")) FROM Table
I don't think this is the optimal solution, however, my hope is that the "higher powers that be" within Microsoft that manage Microsoft Access understand exception handling and would provide some way of testing and handling/ignoring errors, where appropriate.
Regardless, in my case I found a hack to the problem. I save the query just as it was and I exported it to a table. Since this was a one-off exercise, I was able to extract the necessary data and then filter out all Null values from the newly created table.
It worked, but it feels like a really poor hack.
OMGGGGG I know im 6 years late but This is the first time I'm posting on a blog because I actually solved the issue!! You have no idea how excited I am. OK so it turns out this is exactly what I was trying to do: Mid(AField,Instr(Afield,"x")). In my case I knew the InStr function did not always find x in Afield, and in those cases ideally I wanted a Null. But What it actually returns is a 0. In access, functions like Right, Left and Mid CANNOT "START" AT 0, They must start at 1 (or -1 I suppose). Which is what is causing the #Func! error!
One solution....if your Instr fuction=0 do one thing other wise do something else.
If I think of another solution, I let you know.

Some database sanitzation questions

we have a database of around ~250k records which we want to sanitize, and there are some queries which I just don't know how to write:
*clear words containing a substring, for example, if a word contains the substring "cache", delete the entire words, for example:
"cachelkjdlkjalkjs here happened something" => "here happend something"
*delete rows that include more than 2 digits, with exception of couple of cases, for example: the 3 digits 365 are permitted.
so:
"365 days a year, we do that" => Do nothing
"798 is a random number" => DELETE
*check for number of words, and delete records with less than X number of words.
Any help would be appreciated.
First back up the database!
I would first draw up a list of words (along with the numbers 0...99, 365 and any others you think of). I would then create a script (language of yor chosing) to go through the rows. For each row retrieve the words, puncuation, and numbers and then check to ensure that they are valid. For the valid ones reconstruct the entry and spit out the bits that do not match. From the bits that do not match I would just have a look to ensure that you have not missed anything.
I would first do this in a passive mode (i.e. do not change the database) until you a happy that things are ok.
Hope that helps.