BusinessObjects Board

Publishing agnostic docs

Hi,

I had a need to publish several hundred PDFs to Infoview and did not want to do it by hand. I wasn’t able to find any sample code, so I thought that what I wrote might be useful to someone else.

I wrote this as an Excel VBA macro, although it doesn’t actually use Excel.

The code recurses through a given UNC path, publishing all found files into Infoview, keeping the folder structure intact. I’ve only tested it with PDFs, but it should work with all other types.

Joe


Option Explicit
Dim pluginPDF As PluginInfo
Dim pluginExcel As PluginInfo
Dim pluginWord As PluginInfo
Dim pluginTxt As PluginInfo
Dim pluginRtf As PluginInfo
Dim pluginPowerpoint As PluginInfo
Dim pluginAgnostic As PluginInfo
Dim pluginFolder As PluginInfo

Sub loadAgnosticFiles()
    
    Dim userName As String
    Dim userPass As String
    Dim server As String
    Dim auth As String
    
    ' Define the starting UNC path to load files from
    ' IMPORTANT: string MUST end with a backslash
    Dim pathStart As String
    pathStart = "\\server\share\path\"
    
    ' Define the name of the BOE folder to be created
    Dim folderNewReports As String
    folderNewReports = "<folder name>"
    
    ' Define the existing BOE parent folder into which the new structure will be added
    Dim folderExistingParentToPutNewReportsInto As Long
    folderExistingParentToPutNewReportsInto = <parent id>
    
    ' BOE logon parameters
    userName = ""
    userPass = ""
    server = ""
    auth = ""
    
    Dim oSessionMgr As CrystalEnterpriseLib.SessionMgr
    Set oSessionMgr = New CrystalEnterpriseLib.SessionMgr
    
    Dim oEnterpriseSession As CrystalEnterpriseLib.EnterpriseSession
    Set oEnterpriseSession = oSessionMgr.Logon(userName, userPass, server, auth)
    
    Dim oInfoStore As CrystalInfoStoreLib.InfoStore
    Set oInfoStore = oEnterpriseSession.Service("", "InfoStore")
    
    ' Define all the plugin objects
    Set pluginPDF = oInfoStore.PluginManager.PluginInfo("Pdf")
    Set pluginExcel = oInfoStore.PluginManager.PluginInfo("Excel")
    Set pluginWord = oInfoStore.PluginManager.PluginInfo("Word")
    Set pluginTxt = oInfoStore.PluginManager.PluginInfo("Txt")
    Set pluginRtf = oInfoStore.PluginManager.PluginInfo("Rtf")
    Set pluginPowerpoint = oInfoStore.PluginManager.PluginInfo("Powerpoint")
    Set pluginAgnostic = oInfoStore.PluginManager.PluginInfo("Agnostic")
    Set pluginFolder = oInfoStore.PluginManager.PluginInfo("Folder")
    
    Dim newInfoObjects As InfoObjects
    Dim newInfoObject As InfoObject
    
    ' Create new InfoObjects collection
    Set newInfoObjects = oInfoStore.NewInfoObjectCollection
        
    ' Loop
    Call recurse(oInfoStore, newInfoObjects, pathStart, folderNewReports, folderExistingParentToPutNewReportsInto)
    
End Sub

'      Sub: recurse
'     What: Main loop - copies files from specified UNC folder into BOE
'       In: InfoStore
'           InfoObjects     new IO collection created in main
'           String          UNC path to folder; this will grow upon each recursive call as
'                           we go further into the directory structure.
'           String          name of immediate parent folder.  This is just used to entitle
'                           the BOE folder, so it can be different than the actual UNC
'                           path for the initial call.
'           Long            si_id of the folder into which this new folder will be added
'
'      Out: PlugInInfo  of the specified type -- "Agnostic" type if no match
Sub recurse(oInfoStore As InfoStore, oInfoObjects As InfoObjects, parentPath As String, parentName As String, parentID As Long)
    Dim theFile As String
    Dim newObject As InfoObject
    Dim newParentID As Long
    
    ' Create the BOE folder, if it's not already there
    newParentID = getObjectByName(oInfoStore, parentName, "Folder", parentID)
    If newParentID = -1 Then
        Dim newFolder As InfoObject
        Set newFolder = oInfoObjects.Add(pluginFolder)
        newFolder.Title = parentName
        newFolder.parentID = parentID
        newParentID = newFolder.ID
        Call oInfoStore.Commit(oInfoObjects)
    End If
    
    ' Get all files in this directory, add to BOE
    theFile = Dir(parentPath, vbNormal)
    While (theFile <> "")
        Debug.Print "Uploading: " &amp; parentPath &amp; theFile
        Set newObject = oInfoObjects.Add(getPlugIn(theFile))
        newObject.Files.Add (parentPath &amp; theFile)
        newObject.parentID = newParentID
        newObject.Title = Left(theFile, Len(theFile) - 4)
        theFile = Dir()
        Call oInfoStore.Commit(oInfoObjects)
    Wend
    
    Dim subFolders As Collection
    Set subFolders = New Collection
    ' Now recurse through any and all subfolders.  Since we can't use Dir() with
    ' re-entrant code, we have to first create a Collection of all the subfolder names,
    ' then call recurse for each one.
    
    theFile = Dir(parentPath, vbDirectory)
    While (theFile <> "")
        If theFile <> "." And theFile <> ".." And GetAttr(parentPath &amp; theFile) And vbDirectory Then
            subFolders.Add (theFile)
        End If
        theFile = Dir()
    Wend

    Dim x As Long
    For x = 1 To subFolders.Count
        theFile = subFolders.Item(x)
        Call recurse(oInfoStore, oInfoObjects, parentPath &amp; theFile &amp; "\", theFile, newParentID)
    Next
End Sub


' Function: getPlugIn
'     What: Gets the PlugInInfo object for the specified file extension
'       In: String      file extension
'
'      Out: PlugInInfo  of the specified type -- "Agnostic" type if no match
Function getPlugIn(inFile As String) As PluginInfo
    Select Case LCase(Right(inFile, 3))
        Case "pdf": Set getPlugIn = pluginPDF
        Case "xls": Set getPlugIn = pluginExcel
        Case "doc": Set getPlugIn = pluginWord
        Case "txt": Set getPlugIn = pluginTxt
        Case "Rtf": Set getPlugIn = pluginRtf
        Case "ppt": Set getPlugIn = pluginPowerpoint
        Case Else: Set getPlugIn = pluginAgnostic
    End Select
End Function

' Function: getObjectByName
'     What: Checks if the specified object exists in the parent
'       In: InfoStore
'           String      name of the object to look for
'           String      kind of the object to look for (in si_kind format)
'           Long        parent ID to look in
'
'      Out: Long        ID of the object if found, -1 otherwise
'     Note: Only looks in ci_infoobjects, so only folders, reports, etc. are searchable
Function getObjectByName(oInfoStore As InfoStore, strName As String, strKind As String, lParentId As Long) As Long
    Dim oInfoObjects As InfoObjects
    Set oInfoObjects = oInfoStore.Query("select si_id from ci_infoobjects where si_name = '" &amp; strName &amp; "' and si_kind = '" &amp; strKind &amp; "' and si_parentid = " &amp; lParentId)
    If oInfoObjects.Count = 0 Then
        getObjectByName = -1
    Else
        getObjectByName = oInfoObjects.Item(1).ID
    End If
    
End Function

joepeters :us: (BOB member since 2002-08-29)

Thanks for the function Joe, it will be useful.


Joealyche (BOB member since 2012-02-29)

Hi,
I know this was posted a while back but was this done using an SDK? and to which version of Business OBjects, would it work with BI4?

Regards
Goodwin


goodwin (BOB member since 2006-03-06)

I wrote it for XI3 using the COM libraries (Excel VBA). I’m not sure if it’ll work with BI4; but I would guess that it should.

Joe


joepeters :us: (BOB member since 2002-08-29)

This is working for BOE 3.1 , BOE4.0 and BOE 4.1 SP8
but i am getting error when i try to connect BOE4.2 SP04
when click debug this part of the code is highlights

Set oEnterpriseSession = oSessionMgr.Logon(username, userpass, server, auth)

this is the code i am trying to modify
no luck

    Dim oSessionMgr As CrystalEnterpriseLib.SessionMgr
    Set oSessionMgr = New CrystalEnterpriseLib.SessionMgr
    
    Dim oEnterpriseSession As CrystalEnterpriseLib.EnterpriseSession
    Set oEnterpriseSession = oSessionMgr.Logon(username, userpass, server, auth)
    
    Dim oInfoStore As CrystalInfoStoreLib.InfoStore
    Set oInfoStore = oEnterpriseSession.Service("", "InfoStore")

any help
thank you

kum


kum (BOB member since 2004-03-15)

What’s the error? Do you have the Bi4.2 SP04 Client Tools installed?


joepeters :us: (BOB member since 2002-08-29)

i have BOE client tools including crystal reports 2016 installed on my desktop
and also i have crystal reports 2008 installed on my desktop


kum (BOB member since 2004-03-15)

Which version of BI4 client tools?


joepeters :us: (BOB member since 2002-08-29)

client tools are BOE 4.2 sp04 and crystal reports 2016 sp04


kum (BOB member since 2004-03-15)

Ok, now what’s the error message?


joepeters :us: (BOB member since 2002-08-29)

this is part of the VBA code it is pointing
and also i have attached the screenshots of the error messages

End If

        If inEnd <> "" Then
            enddate = CDate(inEnd)
        Else
            enddate = Now
        End If
    Else
        startdate = Date
        enddate = Now
    End If
    start_date = Format(LocalTimeToUTC(startdate), "yyyy.mm.dd.hh:nn:ss")
    end_date = Format(LocalTimeToUTC(enddate), "yyyy.mm.dd.hh:nn:ss")
        
    
    Dim oSessionMgr As CrystalEnterpriseLib.SessionMgr
    Set oSessionMgr = New CrystalEnterpriseLib.SessionMgr
    
    Dim oEnterpriseSession As CrystalEnterpriseLib.EnterpriseSession
    Set oEnterpriseSession = oSessionMgr.Logon(username, userpass, server, auth)
    
    Dim oInfoStore As CrystalInfoStoreLib.InfoStore
    Set oInfoStore = oEnterpriseSession.Service("", "InfoStore")
    
    Dim oInfoObjects As CrystalInfoStoreLib.InfoObjects
        '"SELECT top 64000 SI_KIND,SI_NAME,SI_SCHEDULEINFO.SI_MACHINE_USED,SI_NEXTRUNTIME,SI_SCHEDULEINFO.SI_DESTINATIONS,SI_SCHEDULEINFO.SI_SCHEDULE_TYPE,SI_SCHEDULEINFO.SI_SUBMITTER,SI_SCHEDULEINFO.SI_STARTTIME,SI_STARTTIME,SI_ENDTIME,SI_SCHEDULE_STATUS,SI_STATUSINFO,SI_SCHEDULEINFO.SI_OUTCOME,SI_SCHEDULEINFO.SI_DEPENDENCIES FROM CI_INFOOBJECTS " &amp;
    Set oInfoObjects = oInfoStore.Query("" &amp; _
        "SELECT top 64000 SI_KIND,SI_CREATION_TIME,SI_NAME,SI_SCHEDULEINFO,SI_NEXTRUNTIME,SI_STARTTIME,SI_ENDTIME,SI_SCHEDULE_STATUS,SI_STATUSINFO FROM CI_INFOOBJECTS " &amp; _
        "WHERE SI_INSTANCE = 1 AND SI_COMPONENT = 0 " &amp; _
        "      AND (SI_SCHEDULEINFO.SI_STARTTIME BETWEEN '" &amp; start_date &amp; "' and '" &amp; end_date &amp; "' " &amp; _
        "           OR SI_NEXTRUNTIME < '" &amp; end_date &amp; "' " &amp; _
        "           OR SI_CREATION_TIME BETWEEN '" &amp; start_date &amp; "' and '" &amp; end_date &amp; "')")

kum (BOB member since 2004-03-15)

I don’t see any screenshots.


joepeters :us: (BOB member since 2002-08-29)

please find attachment for VBA error screen shot when run excel
VBA_Error.pdf (3.0 KB)
VBA_Error_code.pdf (18.0 KB)


kum (BOB member since 2004-03-15)

That’s a generic VBA error, so it’s hard to tell what the issue is. I don’t have an environment set up yet with BI4.2 and Office, but I will test it when I do.


joepeters :us: (BOB member since 2002-08-29)

Hi Team,

Please let me know if this code is working for anyone in BI 4.2 We have Bi 4.2 Sp5 on server and I did install client tools of same version on system. I copied this code in vba by creating project but getting error while running it. (attached: vba_project.jpg). Tried this code in .vbs and executed but received error (attached: directvb.jpg)

I also tried to select all 14.0 libraries in Tools>References but got same error.
Please help to solve the issue
vba_project.JPG
directvb.JPG


lokeshborse :india: (BOB member since 2010-09-21)

You will need the following references:
Crystal Enterprise Plugin Manager Library 14.0
Crystal Enterprise InfoStore Library 14.0
Crystal Enterprise Framework Library 14.0


joepeters :us: (BOB member since 2002-08-29)

Thanks. I am able to compile now without any issue. I am not familiar with vba so could you please let me know what to do next to run the code so that document will get uploaded to BO? Our requirement is, we want the agnostic document to get published to BI launchpad in specific folder once users post them to specific UNC path. :roll_eyes:


lokeshborse :india: (BOB member since 2010-09-21)

That’s what this does… You just need to change the values of pathStart and folderNewReports.


joepeters :us: (BOB member since 2002-08-29)

Thanks, but how to run or schedule this code, in excel or any other tool to automate this?


lokeshborse :india: (BOB member since 2010-09-21)

I created it as a one-time job, but I suppose you could add the code to an auto_open macro, and then schedule it with Windows Scheduler. You’d want to add code to it to make sure you don’t upload documents that are already there.

Joe


joepeters :us: (BOB member since 2002-08-29)