MS Access 2010 Form Box Control Source IIF Statement - forms
I am running into the Max Character Issue when trying to put my IIF statement into a box I have created for the calculation of a score on my form. The box code is:
=IIf([cbov1]="na" And [cbov2]="na" And [cbov3]="na" And [cbov4]="na" And [cbov5]="na" And [cboV6]="na" And [cboV7]="na" And [cboV8]="na" And [cboV9]="na" And [cboV10]="na" And [cboV11]="na" And [cboV12]="na" And [cboV13]="na" And [cboi1]="na" And [cboi2]="na" And [cboi3]="na" And [cboi4]="na" And [cbop1]="na" And [cbop2]="na" And [cbop3]="na" And [cbop4]="na" And [cbop5]="na" And [cbop6]="na" And [cbop7]="na" And [cbop8]="na" And [cbop9]="na" And [cbop10]="na" And [cbop11]="na" And [cbof1]="na" And [cbof2]="na" And [cbof3]="na" And [cbof4]="na" And [cbof5]="na" And [cbof6]="na" And [cbof7]="na" And [cbof8]="na" And [cbof9]="na" And [cbof10]="na" And [cbom1]="na" And [cbom2]="na" And [cbom3]="na" And [cbom4]="na" And [cbom5]="na" And [cbom7]="na" And [cbom8]="na" And [cbom9]="na" And [cbom10]="na" And [cbom6]="na",0,(IIf([cboV1]="yes",0,0)+IIf([cbov2]="yes",0,0)+IIf([cbov3]="yes",0,0)+IIf([cbov4]="yes",0,0)+IIf([cbov5]="yes",0,0)+IIf([cboV6]="yes",0,0)+ IIf([cboV7]="yes",0,0)+ IIf([cboV8]="yes",0,0)+ IIf([cboV9]="yes",0,0)+ IIf([cboV10]="yes",0,0)+ IIf([cboV11]="yes",0,0)+ IIf([cboV12]="yes",0,0)+ IIf([cboV13]="yes",0,0)+IIf([cboi1]="yes",5,0)+IIf([cboi2]="yes",3,0)+IIf([cboi3]="yes",3,0)+ IIf([cboi4]="yes",4,0)+IIf([cbop1]="yes",5,0)+IIf([cbop2]="yes",5,0)+IIf([cbop3]="yes",5,0)+IIf([cbop4]="yes",5,0)+ IIf([cbop5]="yes",5,0)+ IIf([cbop6]="yes",4,0)+ IIf([cbop7]="yes",4,0)+ IIf([cbop8]="yes",4,0)+ IIf([cbop9]="yes",4,0)+ IIf([cbop10]="yes",2,0)+IIf([cbop11]="yes",2,0)+IIf([cbof1]="yes",1,0)+IIf([cbof2]="yes",1,0)+IIf([cbof3]="yes",1,0)+IIf([cbof4]="yes",1,0)+ IIf([cbof5]="yes",1,0)+ IIf([cbof6]="yes",1,0)+ IIf([cbof10]="yes",0,0)+ IIf([cbof7]="yes",3,0)+ IIf([cbof8]="yes",3,0)+ IIf([cbof9]="yes",3,0)+IIf([cbom1]="yes",5,0)+IIf([cbom2]="yes",1,0)+IIf([cbom3]="yes",1,0)+IIf([cbom4]="yes",1,0)+IIf([cbom5]="yes",1,0)+IIf([cbom6]="yes",1,0) +IIf([cbom7]="yes",3,0) +IIf([cbom8]="yes",2,0) +IIf([cbom9]="yes",5,0) +IIf([cbom10]="yes",5,0))/(IIf([cboV1]="na",0,0)+IIf([cbov2]="na",0,0)+IIf([cbov3]="na",0,0)+IIf([cbov4]="na",0,0)+IIf([cbov5]="na",0,0)+IIf([cboV6]="na",0,0)+ IIf([cboV7]="na",0,0)+ IIf([cboV8]="na",0,0)+ IIf([cboV9]="na",0,0)+ IIf([cboV10]="na",0,0)+ IIf([cboV11]="na",0,0)+ IIf([cboV12]="na",0,0)+ IIf([cboV13]="na",0,0)+IIf([cboi1]="na",0,5)+IIf([cboi2]="na",0,3)+IIf([cboi3]="na",0,3)+ IIf([cboi4]="na",0,4)+IIf([cbop1]="na",0,5)+IIf([cbop2]="na",0,5)+IIf([cbop3]="na",0,5)+IIf([cbop4]="na",0,5)+ IIf([cbop5]="na",0,5)+ IIf([cbop6]="na",0,4)+ IIf([cbop7]="na",0,4)+ IIf([cbop8]="na",0,4)+ IIf([cbop9]="na",0,4)+ IIf([cbop10]="na",0,2)+ IIf([cbop11]="na",0,2)+IIf([cbof1]="na",0,1)+IIf([cbof2]="na",0,1)+IIf([cbof3]="na",0,1)+IIf([cbof4]="na",0,1)+ +IIf([cbof5]="na",0,1)+ +IIf([cbof6]="na",0,1)+ +IIf([cbof7]="na",0,3)+ +IIf([cbof8]="na",0,3)+ +IIf([cbof9]="na",0,3)+ +IIf([cbof10]="na",0,0)+IIf([cbom1]="na",0,5)+IIf([cbom2]="na",0,1)+IIf([cbom3]="na",0,1)+IIf([cbom4]="na",0,1)+IIf([cbom5]="na",0,1)+IIf([cbom6]="na",0,1) +IIf([cbom7]="na",0,3) +IIf([cbom8]="na",0,2) +IIf([cbom9]="na",0,5) +IIf([cbom10]="na",0,5)))*(IIf([cbov1]="no" Or [cbov2]="no" Or [cbov3]="no" Or [cbov4]="no" Or [cbov5]="no" Or [cboV6]="no" Or [cboV7]="no" Or [cboV8]="no" Or [cboV9]="no" Or [cboV10]="no" Or [cboV11]="no" Or [cboV12]="no" Or [cboV13]="no",0,1))
The purpose of the score is to score "Yes" with points, Score "No" as no points, and then have "NA" remove from the overall score. So if a person has 67 out of 67 points, they get a 100. The maximum points is 100 if all questions are answered "Yes" or "No". I need to have all portions of the calculation because CBOV1-13 have a stipulation of if they are "No" the score is automatically 0%.
I don't know of a work around for the MAX CHARACTER you get within the expression builder on the Control Source box via the properties sheet.
Any help on a work around for this issue or ways to make the code shorten and fit with the same end result would be a huge help.
First, I would be tempted to have my field as a numeric (0,1,2 instead of "na,Yes,No"
Then you could use addition...IIF{cvb01 + Cvb02 +cvb03 = 0, 0 ,...else
Using Strings
I can think of two ways. One in the formula using concatenation (ugly)
IIF[cvb01] & [cvb02] & [cvb03] = "NANANA", 0 , ...Else)
I would be more tempted to write a function to take care of it.
dim NAcount as integer
Dim YesCount as integer
Dim NoCount as integer
dim ctr as integer
dim StrAns as string
for ctr = 1 to 10
StrAns = Fields ("cvb" & Ctr)
Select case StrAns
Case "NA"
NaCount = NACount + 1
'...add values here
Case "Yes"
'...more values go here
Case "No"
'... more values
End Select
Next Ctr
...
Related
VBA Vlookup of range of dates in different sheets
I have zero coding experience and am new to VBA, so I don’t even know basics, but giving it a shot. I have a Workbook, with multiple sheet in it. The one that I care about are 2 sheets called DG, and Asp. DG has a button that grabs raw data from a server and populates the sheets ( multiple date columns with data value in adjacent cells). Asp has a button that grabs data as well but on a 30-day avg so every day in a month (columns A in Asp). This is the same case with DG sheet, but DG has data from different dates in a month, because it is not a 30 day pull. So that sets an image for you, now what I want to do is create a button, with a code that can go through a date column in DG and match it with a date from asp date and if there is a match, then copy and paste the adjacent cells values in DG to asp. This is what I have so far with searches on the internet, showing just a vlookup for a single columns I want filled out in Asp, but its not working Private Sub CommandButton2_Click() Dim results As Double Dim ws1 As Worksheet Dim ws2 As Worksheet Dim lrow As Long Dim i As Long Set ws1 = Worksheets("DG") Set ws2 = Worksheets("Asp") lrow = Worksheets("Asp").Range("A5", ws2.Range("A5").End(xlUp)).Rows.Count For i = 5 To lrow On Error Resume Next result = Application.WorksheetFunction.VLookup((ws2.Range("A5" & i)), (ws1.Range("A11:B200")), 2, True) ws2.Range("AG5").Value = result If Err.Number = 0 Then End If On Error GoTo 0 Next i End Sub DG [1]: https://i.stack.imgur.com/ZrwfZ.jpg ASP [2]: https://i.stack.imgur.com/tTsl0.jpg
It's Friday, Here you go, something to look at and study. I am sorry I didn't use Vlookup, I have spent too much time chasing ghosts with that. Perhaps others have had better success, I think what I don't like is Vlookup if it fails an exact match sometimes it chooses an adjacent row and throws everything into turmoil. Here it is: Option Explicit Private Sub CommandButton2_Click() Dim ws1 As Worksheet Dim ws2 As Worksheet Dim lrow2 As Long Dim lrow1 As Long Dim firstDataRow As Double Dim matchRange As Range Dim matchRow As Long Dim i As Long 'Set up your Worksheet variables Set ws1 = ThisWorkbook.Worksheets("DG") Set ws2 = ThisWorkbook.Worksheets("Asp") 'You used A5 several times, so I will assume dates are in Col A and start at row 5 'Set your row with first data, maybe you need two, if they are the same on both sheets you don't firstDataRow = 5 'find the last row on each sheet, using column A, the date col lrow1 = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row lrow2 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row 'In your mind you now have two data ranges, one for each sheet, rows 5-last dat rows 'Pick one sheet, the one with less dates would be more efficient, you mention DG has less 'So this might be built backwards from what you are thinking, since we are iterating each row in the col 'You want to use the shrter call, IF you know its shorter (your comments) 'Loop through each row trying to find a match on your other sheet For i = firstDataRow To lrow1 If ws1.Cells(i, "A") <> "" Then 'Test for empty 'Here is the premise of Find/Match over Vlookup Set matchRange = ws2.Range("A" & firstDataRow & ":A" & lrow2).Find(ws1.Cells(i, "A")) On Error Resume Next matchRow = matchRange.Row 'Returns row number or nothing If (Not matchRange Is Nothing) Then 'we have a row number matched on Asp, for our search item on DG 'perform the "Copy", this can be done differently but here I am going to introduce you to a way 'that can later be used with offsets and col #s, so that you may skip columns, data is not always adjacent ws2.Cells(matchRow, "E") = ws1.Cells(i, "B") ws2.Cells(matchRow, "F") = ws1.Cells(i, "C") ws2.Cells(matchRow, "G") = ws1.Cells(i, "D") Else 'DO NOTHING End If Else 'DO NOTHING End If Next i MsgBox "Search and Copy is complete.", vbInformation, "Completed" End Sub There is so much more to talk about in even this simple project to make this more bullet proof. But this is a good start for where you are at. Cheers! Happy Coding! - WWC
SSRS Max date from Lookupset
I've spent a long time looking around for a solution for this and not found quite what I want. Efforts to adapt existing solutions for different problems have also not worked! I am using LookupSet to return a list of dates, then joining them to return a list: =Join(LookupSet(Fields!cPatSer.Value,Fields!cPatSer.Value,Fields!DDate.Value,"PatD")) I want to only show the most recent date from that list. Here is what I have tried so far: The above function wrapped in a Max function (doesn't work because Join returns a string) Using a split function to split the resultant string looking for the commas then using the max function Doing both of the above but converting the output to Date objects using CDate and DateTime.Parse first as follows... =Join(LookupSet(Fields!cPatSer.Value,Fields!cPatSer.Value,CDate(Fields!DDate.Value),"PatD")) =Join(LookupSet(Fields!cPatSer.Value,Fields!cPatSer.Value,DateTime.Parse(Fields!DDate.Value),"PatD")) Can anybody provide any pointers please?
I've found a solution using Custom Code. Oz Locke made a function that does various aggregates for integer data (links below), and I've amended this to work for dates instead. In the Code property of the report, paste in this: 'Amended from Oz Locke's code: 'https://github.com/OzLocke/SSRSAggLookup/blob/master/AggLookup.vb 'Allows users to adjust the aggregation type of lookupsets in a cell Function AggLookup(ByVal choice As String, ByVal items As Object) 'Ensure passed array is not empty 'Return a zero so you don't have to allow for Nothing If items Is Nothing Then Return 0 End If 'Define names and data types for all variables Dim current As Date Dim count As Integer Dim min As Date Dim max As Date Dim err As String 'Define values for variables where required current = CDate("01/01/1900") count = 0 err = "" 'Calculate and set variable values For Each item As Object In items 'Calculate Count count += 1 'Check value is a number If IsDate(item) Then 'Set current current = CDate(item) 'Calculate Min If min = Nothing Then min = current End If If min > current Then min = current End If 'Calculate the Max If max = Nothing Then max = current End If If max < current Then max = current End If 'If value is not a number return "NaN" Else err = "NaN" End If Next 'Select and set output based on user choice or parameter one If err = "NaN" Then If choice = "count" Then Return count Else Return 0 End If Else Select Case choice Case "count" Return count Case "min" Return min Case "max" Return max End Select End If End Function Then in the cell of your report, use this expression: =code.AggLookup("max", LookupSet(Fields!cPatSer.Value,Fields!cPatSer.Value,Fields!DDate.Value,"PatD")) https://itsalocke.com/aggregate-on-a-lookup-in-ssrs/ https://github.com/OzLocke/SSRSAggLookup/blob/master/AggLookup.vb
Calculation of Previous field
New to CR and use CR v10 and SQL Server 2000. For the first record i.e Beginning Balance , the calculation is sum(field) from the input date, which I have calculated in SP as BegDateSum But for the rest of the records under a group, the calculation should be previous(balance)+IN+OUT Sample has been given: Date Doc Descrip IN OUT Balance Group Header-------- Beginning Balance-------------- 50 <---- sum(field) from my inputdate 3/2/2012 A -1 0 49 <-- (50+(-1)+0) 4/2/2012 B -2 0 47 <-- (49+(-2)+0) 5/2/2012 C 0 3 50 6/2/2012 D -2 3 51 How do I achieve this? I am not sure whether to use running total, in case I have to how to do it.
A running total field won't work in this case, they are designed to add up (or count, or average, etc) one field and give you the sub-totals automatically. But, we can do some custom functions that will give the results you need. Assuming that your initial 50 is a static value, you would set a variable to that amount, and then add the IN and OUT values as you go along (printing that result of that). First, initialize the value in the report header with a formula like: WhilePrintingRecords; Global NumberVar Balance; Balance := 50; ""; //print nothing on the screen Then, the formula to calculate and show the new balance, in the bar where the data is: WhilePrintingRecords; Global NumberVar Balance; Balance := Balance + {tableName.IN} + {tableName.OUT}; The last line both calculates the new value, and tells what the result of the formula should be. If the "50" is calculated somehow, then that will have to be done before the formula that calculates the new balance. If it is based off of the first record read in, you'll want to use a formula that includes If PreviousIsNull({tableName.Balance}) Then ..., that is usually a good indicator of the first record in the data set (unless that field can be null).
sum two values from different datasets using lookups in report builder
I have a report that should read values from 2 dataset by Currency: Dataset1: Production Total Dataset2: Net Total Ive tried to use: Lookup(Fields!Currency_Type.Value, Fields!Currency_Type1.Value, Fields!Gross_Premium_Amount.Value, "DataSet2") This returns only the first amount from dataset 2. I've tried Lookupset function as well but it didn't SUM the retrieved values. Any help would be appreciated.
Thanks Jamie for the reply. THis is what i have done and it worked perfect: From Report Properties--> Code , write the below function: Function SumLookup(ByVal items As Object()) As Decimal If items Is Nothing Then Return Nothing End If Dim suma As Decimal = New Decimal() Dim ct as Integer = New Integer() suma = 0 ct = 0 For Each item As Object In items suma += Convert.ToDecimal(item) Next If (ct = 0) Then return 0 else return suma End Function Then you can call the function: code.SumLookup(LookupSet(Fields!Currency_Type.Value, Fields!Currency_Type1.Value,Fields!Gross_Premium_Amount.Value, "DataSet2"))
Yes, Lookup will only return the first matching value. Three options come to mind: Change your query, so that you only need to get one value: use a GROUP BY and SUM(...) to combine your two rows in the query. If you are using this query other places, then make a copy and change that. Is there some difference in the rows? Such as one is for last year and one is for this year? If so, create an artificial lookup key and lookup the two values separately: =Lookup(Fields!Currency_Type.Value & "," & YEAR(DATEADD(DateInterval.Year,-1,today())), Fields!Currency_Type1.Value & "," & Fields!Year.Value, Fields!Gross_Premium_Amount.Value, "DataSet2") + Lookup(Fields!Currency_Type.Value & "," & YEAR(today()), Fields!Currency_Type1.Value & "," & Fields!Year.Value, Fields!Gross_Premium_Amount.Value, "DataSet2") Use the LookupSet function as mentioned. With this you'll get a collection of the values back, and then need to add those together. The easiest way to do this is with embedded code in the report. Add this function to the report's code: Function AddList(ByVal items As Object()) As Double If items Is Nothing Then Return 0 End If Dim Total as Double Total = 0 For Each item As Object In items Total = Total + CDbl(item) Next Return Total End Function Now call that with: =Code.AddList(LookupSet(Fields!Currency_Type.Value, Fields!Currency_Type1.Value, Fields!Gross_Premium_Amount.Value, "DataSet2")) (Note: this code was not tested. I just composed it in the Stack Overflow edit window & I'm no fan of VB. But it should give you a good idea of what to do.)
T-SQL: How to make a positive value turn into the equivalent negative value (e.g "10.00" to "-10.00"
Ok so i have a DECIMAL field called "Score". (e.g 10.00) Now, in my SP, i want to increment/decrement the value of this field in update transactions. So i might want to do this: SET #NewScore = #CurrentScore + #Points Where #Points is the value im going to increment/decrement. Now lets say #Points = 10.00. In a certain scenario, i want 10.00 to become -10.00 So the statement would be translated to: SET #NewScore = #CurrentScore + -10.00 How can i do that? I know its a strange question, but basically i want that statement to be dynamic, in that i dont want to have a different statement for incrementing/decrementing the value. I just want something like this: SET #Points = 10.00 IF #ActivityBeingPerformedIsFoo BEGIN -- SET #Points to be equivalent negative value, (e.g -10.00) END SET #NewScore = #CurrentScore + #Points
Can't you just multiply it by -1?
I always do 0 - #Points. It was this way in some code I inherited. "A foolish consistency..."
Multiply #Points by -1 in that certain scenario.
I thought of subtracting it with a multiple of 2, i.e. x - 2x