I am trying to use an excel like 'Countifs' function in Business Objects, but it always outputs 1 which is incorrect. How do I replicate this to Business Objects?
=IF(COUNTIFS('TabOne'!A:A,[#[Account Number]],'TabOne'!H:H,[#[Order Date]],'TabOne'!D:D,[#[Employee ID]])>0,1,0)
Here is my attempt in Business Objects...
=Count(If
([TabOne].[Account Number]=[TabTwo].[Account Number])
And
([TabOne].[Order Date] = [TabTwo].[Order Date])
And
([TabOne].[Employee ID] = [TabTwo].[Employee ID]) > 0 Then 1 Else 0)
Related
I have a header section which is showing totals etc. I have two fields in another dataset (dataset estimates) which I want to pull into header dataset.
Fee (circled) = IIf(Right(Fields!ProjCategoryId.Value, 3) <> "EXP", Fields!Value.Value, 0)
3rd Party (circled) = IIf(Right(Fields!ProjCategoryId.Value, 3) = "EXP", Fields!Value.Value, 0)
I know you can sum datasets from another dataset with no issues, but how to use IIF etc. as well?
You can use custom code and a lookupset().
Code:
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)
ct += 1
Next
If (ct = 0) Then return 0 else return suma
End Function
To add this, right-click on the blue background of the report and select Report Properties.
Click on the Code option.
Paste it into this window
Call this with =Code.SumLookup(lookupset("EXP", right(Fields!ProjCategoryId.Value, 3), Fields!Value.Value, "DatasetName")) in your expression where you want the number to appear
This will add up all the Values where the ProjCategoryId starts with "EXP".
For <> "EXP", you might need to do several calls to it to add them all up for each thing that it can start with. For example..
Code.SumLookup(lookupset("ONE", right(Fields!ProjCategoryId.Value, 3), Fields!Value.Value, "DatasetName")) + Code.SumLookup(lookupset("TWO", right(Fields!ProjCategoryId.Value, 3), Fields!Value.Value, "DatasetName"))
This is actually really simple. Find the Textbox name that contains the expression.
(When we say textbox this does not have to be a textbox from the toolbox, it can be a field within tablix). Where you want to reference the value simply add the expression and you can reference the result.
I have a 100% Stacked Bar chart. Students are banded based on their attendance,and the report simply tracks changes in the band populations as a percentage of the total student population. In Report Builder, this works totally fine (except in that it highlights our rubbish attendance of course...)
The problem arises when:
The report is exported from Report Builder to PDF/Word/Excel/whatever
The report is deployed to an SSRS server and run through the browser
You change to a subsequent page of the report, and then change back to the page with the graph.
In all case although the actual chart remains unchanged, the Legend loses its mind a little bit and shows the top three items as 100%:
I can't think of any reason that that should happen...the report was particularly finicky to make as a result of the underlying data structure (which regrettably is based on a Report Model, meaning I can't tweak it with SQL) and I had to use custom vb code in the end to get it to do what I wanted, but I can't see why any of that should change its behaviour either on the server or when exported.
So my question is; why does this happen, and how do I stop it happening?
EDIT: By Request:
The dataset inherently returns data in the format below. There's a row per learner ID per "Week Start Date".
The custom code I am using is pasted below (inept I know - no laughing!):
Private attendance_table As New System.Collections.Hashtable()
Private last_added_table As New System.Collections.Hashtable()
Public Function band_calc(ByVal attendance As Double) As String
REM Define the bands that I want to track
If attendance = 1 Then
Return "A"
ElseIf attendance >= 0.975 Then
Return "B"
ElseIf attendance >= 0.95 Then
Return "C"
ElseIf attendance >= 0.925 Then
Return "D"
ElseIf attendance >= 0.90 Then
Return "E"
ElseIf attendance >= 0.85 Then
Return "F"
ElseIf attendance >= 0.8 Then
Return "G"
Else
Return "X"
End If
End Function
Public Function get_attendance_band(ByVal week_start_date as String, ByVal learnerID As Integer, ByVal possibles As Integer, ByVal presents As Integer) As String
If attendance_table Is Nothing Then
Dim attendance_table As New System.Collections.Hashtable()
End If
If last_added_table Is Nothing Then
Dim last_added_table As New System.Collections.Hashtable()
End If
REM check if attendance_table has the Learner already
If attendance_table.ContainsKey(learnerID) Then
REM check if we've already added this week's data in
If attendance_table(learnerID).ContainsKey(week_start_date) Then
REM just return the band_calc for those data
Return band_calc(attendance_table(learnerID)(week_start_date)(1) / attendance_table(learnerID)(week_start_date)(0))
Else
REM Add in this week to the hashtable. Add this weeks data to the last weeks data
attendance_table(learnerID).Add(week_start_date, New Object() { possibles + attendance_table(learnerID)(last_added_table(learnerID))(0), presents + attendance_table(learnerID)(last_added_table(learnerID))(1)})
REM record that this is now the last date updated for this learner
last_added_table(learnerID) = week_start_date
REM show the band!
Return band_calc(attendance_table(learnerID)(week_start_date)(1) / attendance_table(learnerID)(week_start_date)(0))
End If
Else
attendance_table.Add(learnerID, New System.Collections.Hashtable())
attendance_table(learnerID).Add(week_start_date, New Object() {possibles, presents})
last_added_table.Add(learnerID, week_start_date)
Return band_calc(attendance_table(learnerID)(week_start_date)(1) / attendance_table(learnerID)(week_start_date)(0))
End If
End Function
For the series properties; The sort, group and label (which defines the Legend obviously) are all set to this:
I need to update two information on one object: the quantity (PLAF-gsmng) and refresh the planned order via the module function 'MD_SET_ACTION_PLAF'.
I successfully find a way to update each data separately. But when I execute the both solutions the second modification is not saved on the database.
Do you know how I can change the quantity & set the action on PLAF (Planned order) table ?
Do you know other module function to update only the quantity ?
Maybe a parameter missing ?
It's like if the second object is locked (sm12 empty, no sy-subrc = locked) ... and the modification is not committed.
I tried to:
change the order of the algorithm (refresh and after, change PLAF)
add, remove, move the COMMIT WORK & COMMIT WORK AND WAIT
add DEQUEUE_ALL or DEQUEUE_EMPLAFE
This is the current code:
1) Read the data
lv_plannedorder = '00000000001'
"Read PLAF data
SELECT SINGLE * FROM PLAF INTO ls_plaf WHERE plnum = lv_plannedorder.
2) Update Quantity data
" Standard configuration for FM MD_PLANNED_ORDER_CHANGE
CLEAR ls_610.
ls_610-nodia = 'X'. " No dialog display
ls_610-bapco = space. " BAPI type. Do not use mode 2 -> Action PLAF-MDACC will be autmatically set up to APCH by the FM
ls_610-bapix = 'X'. " Run BAPI
ls_610-unlox = 'X'. " Update PLAF
" Customize values
MOVE p_gsmng TO ls_plaf-gsmng. " Change quantity value
MOVE sy-datlo TO ls_plaf-mdacd. " Change by/datetime, because ls_610-bapco <> 2.
MOVE sy-uzeit TO ls_plaf-mdact.
CALL FUNCTION 'MD_PLANNED_ORDER_CHANGE'
EXPORTING
ecm61o = ls_610
eplaf = ls_plaf
EXCEPTIONS
locked = 1
locking_error = 2
OTHERS = 3.
" Already committed on the module function
" sy-subrc = 0
If I go on the PLAF table, I can see that the quantity is edited. It's working :)
3) Refresh BOM & change Action (MDACC) and others fields
CLEAR ls_imdcd.
ls_imdcd-pafxl = 'X'.
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = lv_plannedorder
iaccto = 'BOME'
iaenkz = 'X'
imdcd = ls_imdcd
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3
OTHERS = 4.
IF sy-subrc = 0.
COMMIT WORK.
ENDIF.
If I go on the table, no modification (only the modif. of the part 2. can be found on it).
Any idea ?
Maybe because the ls_610-bapco = space ?
It should be possible to update planned order quantity with MD_SET_ACTION_PLAF too, at least SAP Help tells us so. Why don't you use it like that?
Its call for changing the quantity should possibly look like this:
DATA: lt_acct LIKE TABLE OF MDACCTO,
ls_acct LIKE LINE OF lt_acct.
ls_acct-accto = 'BOME'.
APPEND lt_acct.
ls_acct-accto = 'CPOD'.
APPEND lt_acct.
is_mdcd-GSMNG = 'value' "updated quantity value
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = iv_plnum
iaenkz = 'X'
IVBKZ = 'X'
imdcd = is_mdcd "filled with your BOME-related data + new quantity
TABLES
TMDACCTO = lt_accto
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3.
So there is no more need for separate call of MD_PLANNED_ORDER_CHANGE anymore and no more problems with update.
I used word possibly because I didn't find any example of this FM call in the Web (and SAP docu is quite ambiguous), so I propose this solution just as is, without verification.
P.S. Possible actions are listed in T46AS table, and possible impact of imdcd fields on order can be checked in MDAC transaction. It is somewhat GUI equivalent of this FM for single order.
So I work for a retail company and was involved in looking at an incident where I systemically had to 'load' some stock onto a trailer, to be dispatched to a store.
So I have an issue with some code which executed, the process is trying to do the following to a SQL table;
UPDATE RESV_LOCN_HDR SET RESV_LOCN_HDR.USER_ID = :1, RESV_LOCN_HDR.CURR_WT = :2, RESV_LOCN_HDR.CURR_VOL = :3, RESV_LOCN_HDR.CURR_UOM_QTY = :4, RESV_LOCN_HDR.MOD_DATE_TIME = :5 WHERE ( RESV_LOCN_HDR.LOCN_ID = :6 )
The input variables for reference are;
input variables
1: Address(309adbdc) Length(0) Type(8) "RFUSER" - Indicator # 309ad7d4 = 0
2: Address(309ae02c) Length(0) Type(4) "11047.4" - Indicator # 309ad9b8 = 0
3: Address(309ae1ac) Length(0) Type(4) "-1.01e+09" - Indicator # 309ada3c = 0
4: Address(309ae32c) Length(0) Type(4) "-57" - Indicator # 309adac0 = 0
5: Address(309ae55c) Length(0) Type(7) "10/27/2016 2:57:50 PM" - Indicator # 309adb70 = 0
6: Address(309ade0c) Length(0) Type(8) "600062508" - Indicator # 309ad8d0 = 0
The columns I am writing to (USER_ID, CURR_WT, CURR_VOL, CURR_UOM_QTY, MOD_DATE_TIME, LOCN_ID all have the following data types;
USER_ID = VARCHAR2(15 CHAR)
CURR_WT, CURR_VOL = NUMBER(13,4)
CURR_UOM_QTY = NUMBER(9,2)
MOD_DATE_TIME = DATE
LOCN_ID = VARCHAR2(10 CHAR)
From my understanding (and I'm sure you'll all see the above as well, all the column data types are met apart from 3: CURR_UOM_QTY is trying to write -1.01e+09, now is it just me or is this the reason why the error is being returned? Is it not that the above data is a macro? or something similar?
Just not seen SQL try to write 1.01e+09 before, as it should only be writing numerical data, not a mixture.
Using oracle 11g.
Yes, the value of -1.01e+09 is why you are getting an error since your decimal precision is 4 and that value has many more decimals. It does not automatically round to four decimal places.
I'm creating a RDL and I'm trying to sum hours. The source data type is (numeric(11,4),null).
The expression I'm trying to use is:
=sum(iif(Fields!cal_variance.value > 0, Fields!cal_variance.value,0))
I have also tried:
=sum(iif(Cdbl(Fields!cal_variance.value) > 0, Cdbl(Fields!cal_variance.value),0))
I still get the same error:
"The Value expression for the textbox ‘textbox19’ uses an aggregate function on data of varying data types. Aggregate functions other than First, Last, Previous, Count, and CountDistinct can only aggregate data of a single data type.
Preview complete -- 0 errors, 1 warnings"
I should also mention that the column "cal_variance" is a derived column:
=IIF((Fields!COMMENT.Value) = "DC01 MONTHLY - GROCERY CHECKING"
OR (Fields!COMMENT.Value) = "DC01 MONTHLY - DAIRY CHECKING"
OR (Fields!COMMENT.Value) = "DC01 MONTHLY - PRODUCE CHECKING"
OR (Fields!COMMENT.Value) = "DC01 MONTHLY - MEAT CHECKING"
OR (Fields!COMMENT.Value) = "DC01 MONTHLY - FROZEN CHECKING"
OR (Fields!COMMENT.Value) = "DC01 MONTHLY - FRESH PUTAWAY",
Fields!cal_amount.Value / 9, Fields!cal_stdtime.Value - Fields!cal_actualtime.Value)
Any help is greatly appreciated!
If the underlying field is numeric, you will need to make sure both sides of the IIf are decimal in the SSRS expression:
=Sum(IIf(Fields!cal_variance.value > 0, Fields!cal_variance.value, CDec(0)))
Your second example above fails as you are aggregating a double with an integer.