Remove sas content from Excel with VBA (MS Office Add-in) - vba

I've figured out how to use the MS Office Add-in to run a SAS Stored Process from within Excel (using an input stream) to obtain outputs.
Everytime I run this, new columns are inserted to accommodate the new output. Also, additional content is added to the workbook.
My understanding of the SAS Add-in object model is poor, so I was hoping someone could help me:
1) Remove the existing content with VBA before running the process again; or
2) Write VBA code to refresh existing content only (within the same output range).
The code I'm using is:
Sub sasTests()
Application.ScreenUpdating = False
Dim sas As SASExcelAddIn
Set sas = Application.COMAddIns.Item("SAS.ExcelAddIn").Object
Dim inputStream As SASRanges
Set inputStream = New SASRanges
inputStream.Add "Prompts", Worksheets("sasInput").Range("sasInput")
sas.InsertStoredProcess "/Shared Data/C139/sasTests", _
Worksheets("sasOutput").Range("A1"), , , inputStream
End Sub
Many thanks!
PS. If anyone has any handy references for the SAS Add-in for MS Office, please provide links

You could clear the range containing the existing content with the .Clear method. If this range were in columns M:P, you could use the following line:
sheetNameHere.Range("M:P").Clear
If you added that line after setting
Application.ScreenUpdating = False
I believe this would imitate a "refresh" of the data.

This will remove all old components from the workbook. I am not sure how to refresh all but assuming its similar:
Sub DeleteSasContent()Dim sas As SASExcelAddIn
Set sas = Application.COMAddIns.Item("sas.exceladdin").Object
Dim stpList As SASStoredProcesses
Dim dataList As SASDataViews
Dim pivotList As SASPivotTables
Dim reportList As SASReports
Set stpList = sas.GetStoredProcesses(ThisWorkbook)
Set dataList = sas.GetDataViews(ThisWorkbook)
Set pivotList = sas.GetPivotTables(ThisWorkbook)
Set reportList = sas.GetReports(ThisWorkbook)
For i = 1 To stpList.Count
stpList.Item(i).Delete
Next i
For i = 1 To dataList.Count
dataList.Item(i).Delete
Next i
For i = 1 To pivotList.Count
pivotList.Item(i).Delete
Next i
For i = 1 To reportList.Count
reportList.Item(i).Delete
Next i
End Sub
See the SAS help here http://support.sas.com/kb/45/606.html

Related

Multi criteria filter in VBA (Not equal to)

I am using the below code in Blue prism for filtering in excel for multi criteria.
But i am not able to filter multi criteria for Not equal to scenario.
Dim wb As Object
Dim excel as Object
Dim range as Object
Try
wb = GetWorkbook(Handle, Workbook)
excel = wb.Application
range = excel.Range(FRange)
Dim listOfValues as Array
listOfValues = Split(FCriteria,";")
wb.worksheets(Worksheet).select
range.select
range.Autofilter(FCol,listOfValues,7)
Success = True
Catch e As Exception
Success = False
Message = e.Message
Finally
wb = Nothing
End Try
Please help me tweaking the script
I'm almost sure that there is no filter option to set a "negative list". You can specify either a (positive) list of values (this is what your code does so far, for this you have to set the 7 as third parameter), or you can give a maximum of 2 individual criteria (in Excel, choose "Custom Filter" to set them.
You should play with the filter directly in Excel and try to set it like you want. Once you are satisfied with it, clear the filter, record a macro and repeat the filtering. Go to the VBA editor and see what's in there. It is straightforward to translate this into C# code.
But:
It's not possible to set any filtering by code (neither C# nor VBA) that you cannot set via the Excel GUI
I would question what you are trying to do. Since you are using Blue Prism, you should be trying to access the underlying data in a BP Collection(VB DataTable), rather than applying a filter, which is a visual tool for humans to further play with the interface. The robot will still have to do something with the filtered data, and it far easier to write code to proceed with data during the loop.
Otherwise use the Filter Collection Page of the 'Utilities - Collection Manipulation' VBO to get a filtered collection.
Also you are using VBA Split function, when you should use Split in VB as a method of the String.
Try this for a new page in the 'Utilities - Collection Manipulation' VBO(untested):
Dim NewRow As DataRow
Collection_Out = Collection_In.Clone
Dim Select_Concat As String
Select_Concat = "NOT(" & fieldName & " = '" & [String].Join("' OR " & fieldName & " = '", FCriteria.Split(";"c)) & "')"
For Each parentRow As DataRow In Collection_In.Select(Select_Concat)
NewRow = Collection_Out.NewRow
For Each c As DataColumn In NewRow.Table.Columns
NewRow(c.ColumnName) = parentRow(c.ColumnName)
Next c
Collection_Out.Rows.Add(NewRow)
Next parentRow
NewRow = Nothing
Collection_In = Nothing
Inputs: Collection_In(Collection), fieldName(Text), FCriteria(Text)
Outputs: Collection_Out(Collection)
You first need to get the entire range into an unfiltered Collection(which will be your Collection_In to this page, and then get the filtered Collection out....

Calling a variable in VBA Formula

I am very new in VBA and have the following problem:
I have a code like this
IE.Document.getElementsByName("selectedNotifiers")(tparty).Checked = True
The purpose is to check a checkbox on a website. The code works. Now I want to use tparty as a variable based on a excel cell.
I tired this
Dim tparty As String
tparty = ThisWorkbook.Sheets("Sheet1").Value(Range("q" & rn))
IE.Document.getElementsByName("selectedNotifiers")(tparty).Checked = True
but is causing the IE crashing. Any help plz.
Latest status. even Tried this
Dim tparty As String
tparty = "SFD0087G"
IE.Document.getElementsByName("selectedNotifiers")(tparty).Checked = True
no luck.

VBA replace logo in Excel file

I have a little strange question. I used to have few reports worked upon daily.
All these are in Excel and had a logo of the company in all the sheets of each file.
However, now the company name is changed and hence a new logo needs to be replaced in place of the existing. Wanted to check if this replacement can be done with VBA.
I tried with the application.shapes method. But, was confused to proceed further.
Try this....
Sub ChangePicture(strNewPath As String)
Dim oOld As Picture
Dim oNew As Picture
Set oOld = ActiveSheet.Pictures(1)
Set oNew = ActiveSheet.Pictures.Insert(strNewPath)
oNew.Left = oOld.Left
oNew.Top = oOld.Top
oNew.Width = oOld.Width
oNew.Height = oOld.Height
oOld.Delete
End Sub

VBA: clear data from an object(Array) (SAP Object in VBA)

I am an SAP developer with little knowledge of VBA.
I am creating an VBA to post data to SAP using a BAPI. The coding is working fine & I am able to post data into SAP. My problem is I have several rows in my excel, I have to loop the rows one by one & upload data in SAP, after each upload i need to clear the contents, I am unaware of what syntax needs to be used to clear the data of the object variable. Below is the code snippet..
Set objbapicontrol = CreateObject("SAP.Functions")
Set objbapi = objbapicontrol.Add("BAPI_PO_CREATE1")
Set poheader = objbapi.exports.Item("POHEADER")
Set poitems = objbapi.tables.Item("POITEM")
For Each row In [POHEAD].Rows '##PO Header
If row.Columns(row.ListObject.ListColumns("SAP_PO_NUM").Index).Value = "" Then
ponum = (row.Columns(row.ListObject.ListColumns("PONumber").Index).Value)
poheader.Value("COMP_CODE") = (row.Columns(row.ListObject.ListColumns("COCD").Index).Value)
i = "00001"
n = 1
'###Loop Detail
For Each rowd In [PODET].Rows '##PO Detail
If (rowd.Columns(rowd.ListObject.ListColumns("PONumber").Index).Value) = ponum Then
poitem = (rowd.Columns(rowd.ListObject.ListColumns("Itemnumber").Index).Value)
poitems.Rows.Add
poitemsx.Rows.Add
poitems.Value(n, "PO_ITEM") = i
poitems.Value(n, "MATERIAL") = Material
Next '##PO Detail
returnfunc = objbapi.call
ponumber = objbapi.imports("EXPPURCHASEORDER")
Set retmess = objbapi.tables.Item("RETURN")
Set poitems = Nothing
next
I am using the code "Set POITEMS = NOTHING" but again when I set the object, the previous data is not cleared & duplicate enteries are created in SAP
Thanks in Advance!!
Regards,
Anil Malhotra
try using Set poitems = objbapi.tables.Item("POITEM") under the For loop.
set poitems= NOTHING will destroy the object but sometimes do not clear data. I faced this issue and was solved by moving the object creating code to the loop.
Hope it helps :)

Update a table linked to a PowerPivot datamodel using EPPlus and it corrupts the datamodel

Using EPPlus I read an XLSX file.
I replace the data in a table and set the table range.
When I open the resulting spreadsheet I get an error:
"We found a problem with some content in 'MySpreadsheet.xlsx'. Do you want us to try to recover as much as we can?" -- I click Yes and I get another error:
"Excel was able to open the file by repairing or removing the unreadable content. Removed Part: Data store"
The error only happens after I add this table to a PowerPivot data model.
[EDIT] - I created a win forms app that reproduces this problem. You
can download it at here
I found the problem but don't know how
to fix it.
rename the xlsx to zip
Open the zip and browse to the xl\workbook.xml file
Look for the node collection.
Notice how EPPlus changes the <definedNames> collection to use absolute cell addresses.
Excel: <definedName name="_xlcn.LinkedTable_MyDate" hidden="1">MyDate[]</definedName>
EPPlus: <definedName name="_xlcn.LinkedTable_MyDate" hidden="1">'MyDate'!$A$2:$A$5</definedName>
If I modify this line after EPPlus is done saving then I can pull it
up in Excel without corrupting the Data Model.
I tried changing the WorkbookXml but it is happening when the
ExcelPackage.Save method runs.
For Each node In pck.Workbook.WorkbookXml.GetElementsByTagName("definedNames")(0).ChildNodes
node.innerText = "MyDate[]"
Next
Any ideas?
Try this first: create a spreadsheet with one table in it. Name the worksheet and table "DateList". Save it and run the below code on it -- it will work.
Then do this: open the same spreadsheet and add the DateList table to a pivottable data model. Save it and run the below code on it -- it will fail.
Here's some code from my MVC Controller -- only the relevant bits:
Public Class ScorecardProgressReportDatesVM
Public Property WeekRange As Date
End Class
Public Function GetScorecardProgressReport(id As Integer) As ActionResult
Dim contentType As String = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Dim DateList As New List(Of ScorecardProgressReportDatesVM)
DateList.Add(New ScorecardProgressReportDatesVM With {.WeekRange = CDate("Jan 1, 2015")})
DateList.Add(New ScorecardProgressReportDatesVM With {.WeekRange = CDate("Jan 1, 2015")})
Dim templateFile As New IO.FileInfo("c:\test.xlsx")
Dim ms As New IO.MemoryStream
Using pck As New ExcelPackage(templateFile)
ExtendTable(pck, "DateList", DateList)
pck.SaveAs(ms)
ms.Position = 0
End Using
Dim fsr = New FileStreamResult(ms, contentType)
fsr.FileDownloadName = "StipProgress.xlsx"
Return fsr
End Function
Private Sub ExtendTable(package As ExcelPackage, tableName As String, newList As Object)
Dim ws As OfficeOpenXml.ExcelWorksheet
ws = package.Workbook.Worksheets(tableName)
Dim OutRange = ws.Cells("A1").LoadFromCollection(newList, True)
Dim t = ws.Tables(tableName)
Dim te = t.TableXml.DocumentElement
Dim newRange = String.Format("{0}:{1}", t.Address.Start.Address, OutRange.End.Address)
te.Attributes("ref").Value = newRange
te("autoFilter").Attributes("ref").Value = newRange
End Sub
In order to fix this we had to change the EPPlus v4.04 source code.
ExcelWorkbook.cs # line 975 was changed
//elem.InnerText = name.FullAddressAbsolute; This was causing issues with power pivot
to
elem.InnerText = name.FullAddress; //Changed to full address... so far everything is working