Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
reganmacdonald
Participant
107,953
If you have wanted to auto-update your BW files using a dynamic selection of variables and filters, then this blog may be useful to you.

What I’ll cover is how I’ve been able to do this with Excel VBA and Analysis for Office (AO).

My previous posts have covered automated Refreshing of AO and BEX files, and then the auto-distribution of those refreshed files, all via VBA and VBscript.

This blog builds on that and introduces the ability to control the Variables and Filters in those files too, via an external file containing the values you want to use.

An example of where this may be useful is the daily/weekly/monthly distribution of BW reports for a wide range of people that have a wide range of requirements, even though it may be drawing from the same Query/Report each time.

i.e. a Financial Results Report needs to go to 15 different departments with a different selection criteria for each department.

Here is the simplified version of what we are trying to do :



The Distribution Master File will look through a list of AO workbooks and their associated parameter files and process each one.

It will first load the parameter file and put those parameters in memory, then it will then load and refresh the relevant AO file using the parameters.

Those parameters may result in the same original file being manipulated and distributed multiple times.

In this blog we will start small and build on it.

  • First Step – The basics of Variables and Filters via VBA

  • Second Step – Supplying Variables and Filters in bulk

  • Third Step – Dynamic Variables and Filters

  • Fourth Step – Clearing out previous settings before using new ones

  • Fifth Step – Saving/Emailing

  • Sixth Step – Putting it all together


Each of the steps after the first one are optional. The further you go, the more functionality your solution can have.

As with the previous post, at the end is an example template and any supporting files. If you want to skip the 'how is it done' part you can just jump to the end and start using it.

This was all done with Analysis for Office 2.3 and Excel 2010. It should work happily on higher versions of both of those too.

 

First Step - The basics of Variables and Filters via VBA


Variables

Setting them
Application.Run("SAPSetVariable", <variable technical name>, <variable value>, "INPUT_STRING", <variable datasource>)

Clearing them
Application.Run("SAPSetVariable", <variable technical name>, "", "INPUT_STRING", <variable datasource>)

Filters

Setting them
Application.Run("SAPSetFilter", <filter datasource>, <filter technical name>, <filter value>, "INPUT_STRING")

Clearing them
Application.Run("SAPSetFilter", <filter datasource>, <filter technical name>, "", "INPUT_STRING")

Refresh your datasource before doing anything with it!

You need to refresh your datasource when you first load the workbook before you can do anything with the Variables and Filters.
Application.Run("SAPExecuteCommand", "RefreshData")

Speeding things up

Similar to turning off screen updating to speed up excel macros, AO has some options too.

You can prepare a bunch of Variables or Filters and then have the refresh of your data happen just once, instead of updating after each one has been submitted.

For Variables, put this code before :
Call Application.Run("SAPSetRefreshBehaviour", "Off")

Call Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "On")

And this after :
Call Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "Off")

Call Application.Run("SAPSetRefreshBehaviour", "On")

It will turn off refreshing and also the submitting of your variables until you are done. This will let you set up a lot of variables at one time, then do a single refresh at the end.

For Filters, you can just make use of the SAPSetRefreshBehaviour option.

Before your filter :
Call Application.Run("SAPSetRefreshBehaviour", "Off")

After your filter :
Call Application.Run("SAPSetRefreshBehaviour", "On")

Additional points


Why use INPUT_STRING instead of any other field options?

It gives you plenty of control over what is entered but is clean and simple to understand. Nothing wrong with the others but INPUT_STRING seems to be the most flexible and easy to use for my purposes.

A single input string can contain all entries in an easily readable and usable form.

For example : Jan; Mar – Aug; !May; Dec

That example string will include January, March through to August and December, and exclude May.

The AO Plugin user guide has examples of the various entries and symbols you can make use of.

There is however a misleading entry in the AO Plugin user guide.

If doing a value range, be sure to put spaces either side of the dash. Use 1 - 5 not 1-5

Variables and making use of the right technical name

One of the non-obvious things when making use of Variables is choosing the right technical name.

If your Query design has the characteristic making using of a selection variable, you need to use the technical name of the variable, not the technical name of the characteristic.

For example, in the screenshot below instead of using 0PLANT to submit a value for Site, I need to use the selection variable S_SITE instead.



That tip was mentioned in this thread : https://archive.sap.com/discussions/thread/3242990

For filters its easy, you would just use the 0PLANT technical name in this case.

 

Second Step – Supplying Variables and Filters in bulk


The easiest way to supply and manage multiple variables and filters is via a standard excel table.

I’ve used the following table in my parameters file. It is formatted as a table and has the name PARAMETERS. It is also on a worksheet named ‘Parameters’.



  • Loop Number : Each update will use a unique loop number. Anything with the same loop number will be processed as the same group.

  • Data Source : The AO data source technical name in the file you are refreshing.

  • Type : Says whether we want to update a Variable or a Filter

  • Field/Selection Variable : The technical name of the Variable or Filter

  • Value : The value you want to use.


So in the example table above we are separately updating the same file 4 times (4 loops). That file has two data sources in it. We have the following updates happening.

  • Loop 1 : Update two variables for DS_1

  • Loop 2 : Update one variable and one filter for DS_1

  • Loop 3 : Update one variable for DS_2

  • Loop 4 : Update one variable and one filter for DS_2


After each Loop is done you can then do anything you want with the file. Save as a new name or email a copy to someone etc.

With a single parameters table, you could have hundreds of loops each doing a different thing on your BW file.

In a single loop there is also nothing to stop you from updating multiple Data sources, like this :



How do we make use of the table? With the following code that loads it up and then loops through it in memory.
' Set up some variables first
Dim lresult, mytable As ListObject
Dim paramatersarray As Variant
Dim Field_Value As String, Filter_Value As String, Field_Datasource As String, Field_Type As String
Dim wb As Workbook

' Lets put the PARAMETERS table into memory in an internal array
' We only want the data, not the headings, so we refer to DataBodyRange on the table

' open the parameters file read only
Set wb = Workbooks.Open(<path and filename of your parameter file>, True, True)

' Now take a copy of the parameters table into memory
Set mytable = wb.Sheets("Parameters").ListObjects("PARAMETERS")
paramatersarray = mytable.DataBodyRange

' Now close the parameters file and clear out the memory
wb.Close False
Set wb = Nothing

At this stage we have our parameters in memory in the field parametersarray.

Now we load the file in a new instance of Excel and make sure AO is running correctly and that we are connected to BW.
' Start a new instance of excel, load up the file we want to refresh

Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True

Set wb2 = xlApp.Workbooks.Open(<the data file you want to refresh>, False, False)

' Force the Analysis for Office addin to be enabled on the second instance of Excel

xlApp.Application.StatusBar = "Making sure Analysis for Office addin is active..."
For Each AddIn In xlApp.Application.COMAddIns

If AddIn.progID = "SapExcelAddIn" Then

If AddIn.Connect = False Then
AddIn.Connect = True
ElseIf AddIn.Connect = True Then
AddIn.Connect = False
AddIn.Connect = True
End If

End If

Next

' Now log in to the BW system
lresult = xlApp.Application.Run("SAPLogon", "DS_1", bw_client, bw_user, bw_password)

' Refresh all of the data sources in the whole workbook so we can start making use of it
lresult = xlApp.Application.Run("SAPExecuteCommand", "RefreshData")

We are ready to go. We have our file opened in xlApp and we are connected to BW. We also have our parameters stored in memory in ‘parametersarray’.

We will be adding more to the code below before we are done, so this initially shows the basics of getting it working.
' Now lets loop through the parameters array.
' LBound = Lower Bound, the lowest record number (in this case 1)
' UBound = Upper Bound, the highest record number

myloop = 0 ' setting this to something that won't match during the first loop, as we know everything starts from 1 in the parameter file

For mainloop = LBound(paramatersarray) To UBound(paramatersarray)

' put the fields into easier variables for the moment
Field_Loopnum = paramatersarray(mainloop, 1)
Field_Datasource = paramatersarray(mainloop, 2)
Field_Type = paramatersarray(mainloop, 3)
Field_Field = paramatersarray(mainloop, 4)
Field_Value = paramatersarray(mainloop, 5)

' We also want to see if there is a 'next' record, to determine if we are on the last record of the current loop.
If (mainloop + 1) > UBound(paramatersarray) Then
Field_Loopnum_next = "No more records" ' Doesn't matter what this is, as long as its not the number of the last loop entry
Else
Field_Loopnum_next = paramatersarray(mainloop + 1, 1)
End If

If Field_Loopnum <> myloop Then
' get ready for a new set of variables
' We are going to process variables first so lets turn off variable submissions to keep the speed up

Call xlApp.Application.Run("SAPSetRefreshBehaviour", "Off")
Call xlApp.Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "On")

End If


' If we find a VARIABLE field, action it.
If Field_Type = "VARIABLE" Then

lresult = xlApp.Application.Run("SAPSetVariable", Field_Field, Field_Value, "INPUT_STRING", Field_Datasource)

End If


If Field_Loopnum <> Field_Loopnum_next Then
' the next row in our parameters table has a different loop number, so lets unpause things to refresh the data

Call xlApp.Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "Off")

' At this stage we have set up refreshed the data for variables, but the user may want to then set some filters.
' Loop through the same parameters array from the start again, but this time for the same loop number as the variables and look for filters this time.

For i = LBound(paramatersarray) To UBound(paramatersarray)

Filter_Loopnum = paramatersarray(i, 1)
Filter_DataSource = paramatersarray(mainloop, 2)
Filter_Type = paramatersarray(mainloop, 3)
Filter_Field = paramatersarray(mainloop, 4)
Filter_Value = paramatersarray(mainloop, 5)

If Filter_Loopnum = Field_Loopnum And Filter_Type = "FILTER" Then

lresult = xlApp.Application.Run("SAPSetFilter", Filter_DataSource, Filter_Field, Filter_Value, "INPUT_STRING")

End If

Next i

' We are all done with the filters for this specific loop Now refresh whats on screen

Call xlApp.Application.Run("SAPSetRefreshBehaviour", "On")

' ***************************************************************************
' At this point we now have a refreshed file with all the new variables and filters.
' Now you can save/saveas/email here before you move on to the next loop.
' ***************************************************************************

End If

' make a note of the loop we just finished as we will check it in the next loop

myloop = Field_Loopnum

Next mainloop

The code above will loop through your parameters table, and for each ‘loop number’ grouping it will process the Variables and then after that process the Filters.

That’s the basics of using Variables/Filters via a table covered.

 

Third Step – Dynamic Variables and Filters


By default when supplying the contents of the variable/filter fields we need to be very specific. Especially when it comes to dates.

i.e. I use the format dd.mm.yyyy for specific days and mm.yyyy for specific months. Your format will vary depending on your regional settings and the defaults assigned to the BW account you are using.

  • 20.01.2017

  • 01.2017


This is no good to me if I am wanting to change the dates I use each day (without having to manually change them, defeating the purpose of the automation).

To solve this, we can put text in the value field of our parameters, and then replace them behind the scenes before we pass them on to the AO functions.

i.e. TODAY, YESTERDAY, CURRENTMONTH, LASTMONTH, ENDOFLASTMONTH etc

You can set your VBA code to look for those text strings in your submitted values, and replace them with the correct specific days or months.



In the screenshot above for the Date selector field (DAY_SEL) I am saying use YESTERDAY.

In my code, at runtime it will replace YESTERDAY with yesterdays date.

We initially set up what those dates are :
yesterday = Format(Date - 1, "dd.mm.yyyy")
today = Format(Date, "dd.mm.yyyy")
currentmonth = Format(Date, "mm.yyyy")
lastmonth = Format(Application.WorksheetFunction.EoMonth(Date, -1), "mm.yyyy")
endoflastmonth = Format(DateSerial(Year(Date), Month(Date), 0), "dd.mm.yyyy")

Then when looking at the Value field, we can make a replacement like this :
If <value field> Like "*TODAY*" Then
<value field> = Replace(<value field>, "TODAY", today)
End If

In our main processing loop we would do the following :
If Field_Type = "VARIABLE"  Then

' see if we need to replace some date texts with actual dates
Field_Value = Text_Replace(Field_Value)

lresult = xlApp.Application.Run("SAPSetVariable", Field_Field, Field_Value, "INPUT_STRING", Field_Datasource)

End If

Same for the filters part :
If Filter_Loopnum = Field_Loopnum And Filter_Type = “FILTER” Then

' see if we need to replace some date texts with actual dates
Filter_Value = Text_Replace(Filter_Value)

lresult = xlApp.Application.Run("SAPSetFilter", Filter_DataSource, Filter_Field, Filter_Value, "INPUT_STRING")

End If

And in our code we put in the following Text_Replace function :
Public Function Text_Replace(thetext As String) As String

If thetext Like "*TODAY*" Then
thetext = Replace(thetext, "TODAY", today)
End If

If thetext Like "*YESTERDAY*" Then
thetext = Replace(thetext, "YESTERDAY", yesterday)
End If

If thetext Like "*CURRENTMONTH*" Then
thetext = Replace(thetext, "CURRENTMONTH", currentmonth)
End If

If thetext Like "*ENDOFLASTMONTH*" Then
thetext = Replace(thetext, "ENDOFLASTMONTH", endoflastmonth)
End If

If thetext Like "*LASTMONTH*" Then
thetext = Replace(thetext, "LASTMONTH", lastmonth)
End If

Text_Replace = thetext

End Function

 

Fourth Step – Clearing out previous settings before using new ones


If you are changing the Variables and Filters on the same AO file over and over, you want to be sure that settings used previously are not still lingering around on the file.

You don’t want a selection you used for one department to still be there when generating the data for the next department.

To solve this we introduce the option of clearing out all the Variables or Filters before it starts with the next set of parameters.

There isn’t a direct way to clear everything that I am aware of, so we can instead clear the things that we know are populated.

To do that we read the populated variables and prompts, and then loop through them setting them to "" (double-quotes with no space in between them).

We can also add this feature to our parameters table, so you have full control over it.



We can put in CLEARFILTERS, CLEARVARIABLES and CLEARALL (which clears variables and filters).

We will modify our main loop with the following :
   If Field_Loopnum <> myloop Then

' get ready for a new set of variables for potentially a new DataSource too

' Lets see if we need to undo any variables and filters first

Get_Active_Variables_and_Filters Field_Datasource
Cleanup_the_Datasource Field_Type, Field_Datasource

Call xlApp.Application.Run("SAPSetRefreshBehaviour", "Off")
Call xlApp.Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "On")

End If

The new subroutines will do two things. Get a list of all the populated Variables and Filters, then Clean them all up.

So how are we getting those lists? The next 3 sections show the basics of doing that.

Getting a list of all of the VARIABLES populated for your datasource

Note we don't care about all of the variables, just the ones that have been populated.
Application.Run(“SAPListOfVariables”, <datasource>, "INPUT_STRING", "ALL_FILLED")

Then if you need to, you can use SAPGetVariable to get the technical info. If we are doing a cleanup we need the technical name.
Application.Run(“SAPGetVariable”, <datasource>, <non-technical name>, "TECHNICALNAME")

Getting a list of all of the FILTERS populated on your datasource

Again, we only want the used filters, not the complete list of filters.
Application.Run(“SAPListOfEffectiveFilters”, <datasource>, "INPUT_STRING")

Unfortunately this only gives you the non-technical name of the field (such as ‘Site’ instead of ‘0PLANT’)

You then make use of the overall dimension list to get the technical name associated with that filter field.
Application.Run("SAPListOfDimensions", <datasource>)

We go into more detail on this part in our code later on.

Making use of the Variables list and Filters list without having to first display them on a spare worksheet

A number of forum posts and blogs mention a method where you use the AO functions to write out the data to a spare sheet on your file, then re-read the figures from that sheet.

That is perfectly suitable and will get the job done, but you don’t actually need to do that to make use of the figures.

Instead we can make use of Arrays in VBA.

Getting the list of Variables into an array can be done as follows :
Dim MyVariablesArray As Variant
MyVariablesArray = Application.Run("SAPListOfVariables", <datasource>)

In MyVariablesArray, you will now have all the data that would have traditionally been displayed on the spare sheet.

It can now be manipulated and read like any other array.

So with those three things in mind, here is the code we are using in the Get_Active_Variables_and_Filters subroutine.

Note we have defined a global ‘VariablesArray’ and ‘FiltersArray’ fields previously that this code will use (Dim VariablesArray() As String, FiltersArray() As String).
Sub Get_Active_Variables_and_Filters(ByVal thedatasource As String)

Dim tempVariablesArray As Variant, tempFiltersArray As Variant
Dim DimensionArray As Variant, x As Long
Dim techname As String, mysource As String

' If there is only 1 Variable, then SAPListOfVariables returns a one dimensional array. LBound = 1, UBound = 2
' If there is more than 1 Variable, SAPListOfVariables returns a two dimensional array.
' Same thing happens for SAPListOfEffectiveFilters

' Lets start by grabbing the Variables, Filters and Dimensions into seperate internal arrays.

tempVariablesArray = xlApp.Application.Run("SAPListOfVariables", thedatasource)
tempFiltersArray = xlApp.Application.Run("SAPListOfEffectiveFilters", thedatasource, "INPUT_STRING")
DimensionArray = xlApp.Application.Run("SAPListOfDimensions", thedatasource)

' We want to add to the correct global arrays, so start from row 1

Erase VariablesArray
Erase FiltersArray
ReDim VariablesArray(1 To 1) As String
ReDim FiltersArray(1 To 1) As String

' We grab the Dimensions info because that also holds the technical names of the filters.
' There is no SAPGetFilter function, so we'll make use of the Dimension list instead

'************
' VARIABLES
'************

' Lets count how many records there are in the Variables array
' We know each row has 2 fields, so we divide by 2 later to get the actual number of rows

array_start = 1
array_end = Application.CountA(tempVariablesArray) / 2

If array_end = 1 Then

' We have only 1 real record, so we know VariablesArray is ONE dimensional

techname = xlApp.Application.Run("SAPGetVariable", thedatasource, tempVariablesArray(1), "TECHNICALNAME")

' add the variable technical name to our global VariableArray
VariablesArray(UBound(VariablesArray)) = techname

Else

' We have more than 1 record, so we know VariablesArray is TWO dimensional

For arrayloop = array_start To array_end

techname = xlApp.Application.Run("SAPGetVariable", thedatasource, tempVariablesArray(arrayloop, 1), "TECHNICALNAME")

' add the variable technical name to our global VariableArray
VariablesArray(UBound(VariablesArray)) = techname

Next arrayloop

End If

'**********
' FILTERS
'**********

' Lets count how many records there are in the Filters array
' We know each row has 2 fields, so we divide by 2 later to get the actual number of rows

array_start = 1
array_end = Application.CountA(tempFiltersArray) / 2

If array_end = 1 Then

' We have only 1 real record, so we know FiltersArray is ONE dimensional
' Now lets get the technical name of the filter from the DimensionArray by looping through it
' until we find a match.

techname = ""

For dimensionloop = LBound(DimensionArray) To UBound(DimensionArray)

If DimensionArray(dimensionloop, 2) = FiltersArray(1) Then
techname = DimensionArray(dimensionloop, 1)
Exit For
End If

Next dimensionloop

' add the filter to our global FiltersArray
FiltersArray(UBound(FiltersArray)) = techname

Else

' We have more than 1 real record, so we know FiltersArray is TWO dimensional

For arrayloop = array_start To array_end

' Now lets get the technical name of the filter from the DimensionArray by looping through it
' until we find a match.

techname = ""

For dimensionloop = LBound(DimensionArray) To UBound(DimensionArray)

If DimensionArray(dimensionloop, 2) = tempFiltersArray(arrayloop, 1) Then
techname = DimensionArray(dimensionloop, 1)
Exit For
End If

Next dimensionloop

' add the filter to our global FiltersArray
FiltersArray(UBound(FiltersArray)) = techname

Next arrayloop

End If

' Lets do some cleanup on the temporary arrays

On Error Resume Next
Erase tempVariablesArray
Erase tempFiltersArray
Erase DimensionArray

End Sub

That gives us VariablesArray and FiltersArray now populated with things we can clear.

Those two arrays only hold the technical name of the Variables and Filters. We haven't tried to keep track of what they have in them currently because we are planning on clearing them out anyway.

We will clear it with the following subroutine, which is basically the same as setting the fields, but this time with "" instead of a value.
Private Sub Cleanup_the_Datasource(cleanuptype As String, thedatasource As String)

If cleanuptype = "CLEARALL" Then

' Lets loop through our filters array and clear them out

For i = LBound(FiltersArray) To UBound(FiltersArray)
lresult = xlApp.Application.Run("SAPSetFilter", thedatasource, FiltersArray(i), "", "INPUT_STRING")
Next i

' Pause any refreshing while we work on clearing our variables
Call xlApp.Application.Run("SAPSetRefreshBehaviour", "Off")
Call xlApp.Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "On")

' Loop through the Variables array and clear them out

For i = LBound(VariablesArray) To UBound(VariablesArray)
lresult = xlApp.Application.Run("SAPSetVariable", VariablesArray(i), "", "INPUT_STRING", thedatasource)
Next i

' Temporarily turn back on refreshing to update things
Call xlApp.Application.Run("SAPSetRefreshBehaviour", "On")
Call xlApp.Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "Off")

' And then turn it off again
Call xlApp.Application.Run("SAPSetRefreshBehaviour", "Off")
Call xlApp.Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "On")

ElseIf cleanuptype = "CLEARVARIABLES" Then

' Pause any refreshing while we work on clearing our variables
Call xlApp.Application.Run("SAPSetRefreshBehaviour", "Off")
Call xlApp.Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "On")

' Loop through the Variables array and clear them out

For i = LBound(VariablesArray) To UBound(VariablesArray)
lresult = xlApp.Application.Run("SAPSetVariable", VariablesArray(i), "", "INPUT_STRING", thedatasource)
Next i

' Temporarily turn back on refreshing to update things
Call xlApp.Application.Run("SAPSetRefreshBehaviour", "On")
Call xlApp.Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "Off")

' And then turn it off again
Call xlApp.Application.Run("SAPSetRefreshBehaviour", "Off")
Call xlApp.Application.Run("SAPExecuteCommand", "PauseVariableSubmit", "On")

ElseIf cleanuptype = "CLEARFILTERS" Then

' Lets loop through our filters array and clear them out

For i = LBound(FiltersArray) To UBound(FiltersArray)
lresult = xlApp.Application.Run("SAPSetFilter", thedatasource, FiltersArray(i), "", "INPUT_STRING")
Next i

End If

End Sub

 

Fifth Step – Saving/Emailing


In the previous blog I covered a way to save/change format/email the refreshed BW workbooks automatically.

That was controlled via a central Master Table, and only did one thing to one file at a time.

If we are now also using a parameters table that can change the one file multiple times, we need to move our saving and email options to the parameter file.

I’m adding the entries in green below to the parameters file.

  • Loop Number

  • Data Source

  • Type

  • Field/Selection Variable

  • Value

  • Action

  • New Filename

  • Add Current Date to Filename

  • File Type

  • Email Type

  • Email - Display/Send

  • Email Addresses

  • Email Subject

  • Email Message Body




In our main loop, we would then detect the ACTION type and do things accordingly.
        ' ***************************************************************************
' At this point we now have a refreshed file with all the new variables and filters.
' Now you can save/saveas/email here before you move on to the next loop.
' ***************************************************************************

' Now lets see if there is an action we need to perform on this loop.
' Similar to what we did for the filters, lets do the same for the Action.

For i = LBound(paramatersarray) To UBound(paramatersarray)

Action_Loopnum = paramatersarray(i, 1)
Action_DataSource = paramatersarray(mainloop, 2)
Action_Type = paramatersarray(mainloop, 3)
Action_Field = paramatersarray(mainloop, 4)
Action_Value = paramatersarray(mainloop, 5)

If Action_Loopnum = Field_Loopnum And Filter_Type = "ACTION" Then

' lets read all the action stuff and do something with it.
Action_Action = paramatersarray(i, 6)
Action_NewFilename = paramatersarray(i, 7)
Action_AddDate = paramatersarray(i, 😎
Action_FileType = paramatersarray(i, 9)
Action_EmailType = paramatersarray(i, 10)
Action_EmailDisplay = paramatersarray(i, 11)
Action_EmailAddress = paramatersarray(i, 12)
Action_EmailSubject = paramatersarray(i, 13)
Action_EmailMessage = paramatersarray(i, 14)

' now this is where you make use of the fields and call the relevant saving and emailing subroutines

End If

Next i

 

Sixth Step – Putting it all together


Below is a template that makes use of all of the Steps mentioned above, along with an example Parameters file.

It builds on what was done in the previous two blogs and adds in the new functionality from this blog.

  • Is it bug free? No probably not.

  • Is it elegantly coded? Maybe, but as long as it works the elegance of the code is of secondary importance.

  • Can it be more efficient? Yes most likely.


Our now modified Distribution Master File has a new column called ‘AO Parameter File’.

If that column is populated with a parameter filename (and full path to it), then it will use that Parameter file instead of the rest of the info on that line.

The screenshot below shows just 1 entry with the parameters being used, though you can do it for any of the AO files in the list.



Click the link below for the main template, and then the one below that for an example parameters file.

They should be enough to get you started.





As always any questions, fixes and improvements are welcomed via the comments section below.

Previous Blogs :

Part 1 : Automated updating of BW data in Excel files (BEX & AO) via VBA/VBscript

Part 2 : Automated updating of BW data in Excel files (BEX & AO) via VBA/VBscript – Part 2

The next part of this topic is available here : Analysis for Office and Excel VBA – Lessons learnt
46 Comments
ivan_bondarenko
Participant
0 Kudos
Very-very-very good post! Amazing job done. I like the approach.
reyemsaibot
Active Participant
0 Kudos
Nice Job Regan. Thanks.

 
Former Member
0 Kudos
Great Post. Thank you very much for the effort.

 
Former Member
0 Kudos
Are the files still available? The Dropbox links give 404 errors.
reganmacdonald
Participant
The links are now updated please try them again.
Former Member
0 Kudos
Hi Regan,

 

I would like to know if there is a similar procedure  to set Variables and Filters via VBA using BEx instead of AO.

 

Thanks!
Former Member
0 Kudos
 

Great article.

However, we have SAP Analysis addin version 2.3 and the code to make sure the addin is connected does not work.

addin.Connect=true

throws an error 'add-in cannot be installed'

Has something changed since you wrote this article?
reganmacdonald
Participant
0 Kudos
Hi Daniel,

Nothing has changed from my point of view. Everything was originally written and working on version 2.3 (and also works on 2.4 and 2.5).

Regards,

Regan
Former Member
0 Kudos
 

Regan,

Thanks, I did figure out the problem and it is working now.

Are you aware of a blog, similar to yours here about AO, that walks through setting variables in a BEX workbook?  Or can't something similar be done?
reganmacdonald
Participant
0 Kudos
I'm not aware of one on here specifically, but likely it can be done.

I haven't spent time on it myself as BEX is not as end-user friendly compared with AO, so our business has moved away from it as much as possible.
Former Member
0 Kudos
I know what you mean.  However, our environment has both right now.  I am looking for a model that will allow automation of both BEX and AO with variables.
former_member378939
Discoverer
0 Kudos
Hi Regan!!

Are the files still available?? Dropbox gives me an error.

Could you send the link again?? I'm very interested in this issue.

Thanks a lot!!!!!
reganmacdonald
Participant
reganmacdonald
Participant
0 Kudos
March 2018 : Note the download link in the blog post points to Dropbox which unfortunately keeps changing the link URL.

The final version of this blog series is 0.7 and is also available at the more permanent link on gt.tt : http://ge.tt/92Kodvo2

 
Former Member
0 Kudos
I found this article very useful, thanks!

Regan, can you provide us with an example of how to access/open a file/workbook saved on a SAP Netweaver Platform through VBScript? I'm struggling to find the right file path (or any path) ?

Thanks!
0 Kudos
This is really useful. Thank you!

Question: I am having trouble when i have a variable which is multiple mandatory. I cannot clear the variable first, since at least one variable populated is required before refreshing. When I just try to set the variable with the new one, the old one remains without the new one being added. Any tips?
reganmacdonald
Participant
0 Kudos
Its best to refresh first (with the current variable contents), then update the variable and refresh again. Its that first refresh that allows things to then change afterwards.
former_member609762
Discoverer
0 Kudos

Really helpfull blog, thank you!

I still have one question you can maybe help me with.

It is possible to assign a variable to a data source through

Application.Run(“SAPSetVariable”, <variablename>, <value>, “INPUT_STRING”, <datasource>

Now I want to assign a variable to multiple datasources. Is this possible within one command, like:

Application.Run(“SAPSetVariable”, <variablename>, <value>, “INPUT_STRING”, “DS_1, DS_2")

But this doesn’t work. Is there a way to do this?

reganmacdonald
Participant
0 Kudos
Not as far as I know, you need to do one call per data source.
former_member609762
Discoverer
0 Kudos
Okay, thank you for the quick responce 🙂
former_member523998
Participant
0 Kudos
? article. This saved me: Refresh your datasource before doing anything with it!
0 Kudos

Hello,

How do I create a dimension filter (ex. Period) where with one selection (Ex. May 2019) I will be able to set Analysis to display both April and June as comparison months? I’m not able to achieve this using the member selector. If anyone has any ideas please let me know.

former_member625687
Discoverer
0 Kudos
Dear Regan,

First of all thank you very much for your explanation and comments regarding "Analysis for office Variables via VBA" because it really helped me.

I used your VBA code to automatically add the Variables into the Prompt and refresh my workbook.

I have only just one question and I hope you could help me. In my Prompt I would need to add the information for “Fiscal Year / Period” by selecting two different dates.

With you example file I was able to change all kind of variables but only one for each field. Here for example I should select directly from the Parameters Files (001.2019 – 007.2019).

 

Could you please help me with this issue?

 

It would really help me a lot.

 

Thank you very much for your feedback.

Daniele.

 



 
reganmacdonald
Participant
0 Kudos
You can supply it exactly like that the two options you want separated by <space>-<space>

001.2019 - 007.2019 will give you that full range.

If however you are wanting two individual fields and not the range in between, separate them with ;<space>

001.2019; 007.2019

I hope that helps clarify it.
former_member629155
Discoverer
0 Kudos

Very interesting blog, thanks a lot Regan !

I didn’t managed to logon automatically with SAP Analysis for Microsoft Office version 2.7.600.89395.

I think I’ve tried quite everything, without any success. It seems everything was working fine until 2.5 and above.

I have many “useful” data in the logs, including what the system excepts as parameters for SAPLogon :
com.sap.ip.bi.formulas.EaExcelFunctions.SAPLogon(String iAlias, String iClient, String iUser, String iPassword, String iLanguage, String iAuthenticationType, String iSID)

iAuthenticationType for me is “secLDAP”.

 

Did you managed to use Application.Run(“SAPLogon”, …) with newer Analysis  version ?

reganmacdonald
Participant
0 Kudos
Yes I'm using the same code successfully on that version (2.7.600.89395).
lresult = Application.Run("SAPLogon", <data source>, <client>, <user>, <password>)

What version of Excel are you using?
former_member629155
Discoverer
0 Kudos
I am using Excel 365 and 2010, same result with both versions.
"Logon to SAP BusinessObjects BI Platform" screen is loaded as soon as Application.Run("SAPLogon", <data source>, <client>, <user>, <password>) is executed.

Maybe this is linked to LDAP authentication ?
former_member629631
Discoverer
0 Kudos
Similar to "G.Angla"'s post

 

using SAP Logon 750,  SAP BO Analysis 2.6.201.241, Excel 365

Utilizing the code furnished i can open an excel file and execute the macros perfectly if i double click and launch excel however when i utilize vbs to open the file and execute the macros i get an error "Cannot run the macro 'SAPLogon'.  The macro may not be available in this workbook or all macros may be disabled.". .

The registry setting(s) are correct for launch.  The excel trust center settings for add-ins and macros is set correctly as well. The components in the AO crosstab are correct.

If i end the attempt from vbs and open the same file and execute the macro vbs was trying to execute it logs me in and refreshes seamlessly.  I've noticed even with the vbs and/or vba to load/activate the AnalysisOffice com addin on open that when vbs opens the file the Analysis menu option is not visible - close it/reopen it by double clicking and there it is . . what would cause this behavior

Thank you in advance!!
reganmacdonald
Participant
0 Kudos
Its likely that issue is related to your BW systems authentication setup, potentially only allowing LDAP and not other direct connection options. Potentially try it against another account that isn't set up to use LDAP and see how that goes.
reganmacdonald
Participant
0 Kudos
A couple of possibilities on this one. What are your specific trust settings, are macros set to be enabled by default? The second item that plays up sometimes is if you aren't forcing excel to be visible in your VBA. If its not visible on screen, then some of the macro code for AO doesn't like to behave.
former_member629155
Discoverer
0 Kudos

I also had Michelle’s trouble and here is the VBS/VBA code I use in order to open Excel and have the AO addin enabled :

Set objShell = WScript.CreateObject("WScript.Shell")
set oExec = objShell.Exec (“””C:\Program Files (x86)\SAP BusinessObjects\Office AddIn\BiOfficeLauncher.exe”” /app XLS /lb 3″)

There are a lot of parameters, see here for a complete list : https://help.sap.com/saphelp_boao22/helpdata/en/f2/6e754f6c9b1014bf2c9a7eb0e91070/frameset.htm

Hope this helps ?

 

reganmacdonald regarding my issue, I hope this is not due to a global parameter in CMS. Our “old” BW system used SSO (like SAP) and it was cool. It seems that “Saplogon” command tries to open the connection the same way as SAP. I hope I’m wrong and I hope I’ll find a way to log on automatically.

former_member625687
Discoverer
0 Kudos
Hi Regan, thank you very much for your help.

I tried as you told me and it did not work. I don't know what i am doing wrong.

Below you can see the screenshot regarding the "Paramaters" i put and the one related to the error i got back from the Tool.

Could you please help me?

Thank you again 🙂
reganmacdonald
Participant
0 Kudos
Thats a very nice solution.
former_member629631
Discoverer
0 Kudos
oooh very nice!! can't wait to try this out will advise than you everyone!!
former_member629631
Discoverer
0 Kudos
trust center settings are (a little ashamed to say so) wide open and visibility on everything was set to visible . . going to try the proposed solution below . . thank you!!!
0 Kudos
Hi Regan,

It seems the gt.tt download link has changed or outdated. If still available, could you please update the link?

Thanks a lot! You've done a great job!
former_member725951
Discoverer
0 Kudos
Thank you, super useful stuff!
0 Kudos


Hi Regan,

while I am refreshing this excel file on a remote server I am getting this error through VBA. It does not throw any error when refreshed manually but throws this exception when refreshed from VBA.

I am setting only the date variable value from VBA & and refreshing it.

Can you please help with this?

 
0 Kudos

Hi, guys!

I have the same problem with running VBScript by Task Scheduler.

My script works good, when I launch it manually or by Taks when user loggen  in.

But it doesn't work, when Task is running in background.

How can I make it works?

Thank you in advance!

0 Kudos
great post! txs a lot!
0 Kudos
Thanks for a very useful blog.

I have a question for date-input. What if you don't have a specific date or a date interval. What if it's a before or equal to a date, that has to go into a filter?

I have a BeX, where the Date filter has to be less or equal to a date Fx. <= 01.01.23

Now how would I put that in my code?

vinothclement
Explorer
0 Kudos
Hello Regan, Thank You so much for all the efforts you had put to share your knowledge with us. The code worked like a charm for me.

Quick Question: I have 3 loops of a data source and currently saving them into a PDF with ACTION syntax after every loop. The requirement is to save all the results of all the 3 loops into One PDF file. How do I achieve this?

Thanks, Vinoth
reganmacdonald
Participant
Only a couple of options on that one, as Excel only saves a single PDF per file by default.

  1. Build all off your results onto separate pages/sheets and save that all at once.

  2. Build the three files separately as you do now, keeping track of the filenames, then either call a command line external program that does the merge for you, or something like this : https://www.mrexcel.com/board/threads/combine-multiple-pdf-files-with-vba.1154816/


 
vinothclement
Explorer
0 Kudos

Thank You Regan for your response. I will check both options. Appreciate your help and guidance.

vinothclement
Explorer
0 Kudos

Hi Regan,

I am planning to go with option 2 but looks like I need the Adobe Acrobat API. Trying to get it installed.

Besides, got the below questions, kindly help.

1. My DMF file has 2 different AFO queries maintained.

  • The parameters file has 3 blocks of loops (1,2,3 for DS_1) for the variable selections and filters of the 1st query.
  • The parameters file also has 1 block of the loop for variable selections and filters of the 2nd query (DS_1).

What I am seeing is the VBA processes both the queries for all the loops maintained on the parameters file.

As my queries are different, in the AFO the data source name is going to be DS_1 which I think makes the VBA think the queries are the same.

The expectation is: I want the first query to run loops 1 to 3 for its own selection and the second query only for the selections related to it (i.e.) loop 1.

Could you please advise how to handle this when we need to save different AFO queries into pdf?

2. At this moment, I am accessing the report from a local drive. Is there a way I can modify it to read the queries from SharePoint?

Thank You

Kurt10
Newcomer
0 Kudos

Hi Regan,

will this work for updating prompts, such as the Fiscal Year / Period Interval?

Kurt10_0-1716404926624.png

thank you!

Labels in this area