Replace all in a specific folder - alm

In my Test Plan I have two folders. One with all my active test cases and one with all my archived test cases. I need to replace a lot of 'Affected Module' from one value to another, however - I don't want the folder with archived to be affected by this.
So, is there a way of doing search and replace only on a specific folder (and all the sub-folders) in HP ALM?
As far as I know the search and replace function in grid view replaces all instances of the value so I can't use that directly.

Here is a simple OTA code that updates the field ts_user_04 for all the test case in folder Subject\Automated and its sub-folder from whatever value to Quoting.
Please, change the column name as per your requirement. You can easily find the DB column for any field in HP ALM by going to the Management tab if you have access to it. Even otherwise you can get all the mapping by using OTA. (I hope you have the necessary access)
Inorder to run the OTA code, you need to install ALM Connectivity add-in which you can get it from the tools section in your ALM home page
Public TDconnection
Public reqPath
Public testPath
'Call the main Function
updateAllTests
Public Function login()
Dim almURL, almUserName, almPassword, domain, project
almURL = "https://.saas.hp.com/qcbin/"
almUserName = ""
almPassword = ""
domain = ""
project = ""
testPath = "Subject\Automated" ' Change it as per your folder structure
Set TDconnection = CreateObject("tdapiole80.tdconnection")
TDconnection.ReleaseConnection
TDconnection.InitConnectionEx almURL
TDconnection.login almUserName, almPassword
TDconnection.Connect domain, project
End Function
Public Function updateAllTests()
login
Set TreeMgr = TDconnection.TreeManager
Set TestTree = TreeMgr.NodeByPath(testPath)
If Err.Number = 0 Then
Set comm = TDconnection.Command
comm.CommandText = "update test set ts_user_04='Quoting' where ts_test_id in (select ts_test_id from test, all_lists where ts_subject in (select al_item_id from all_lists where al_absolute_path like (select al_absolute_path from all_lists where al_item_id=" & TestTree.NodeID & ") || '%' ) and ts_subject = al_item_id)"
comm.Execute
End If
logout
MsgBox "Flag Update successful", vbInformation
End Function
Public Function logout()
TDconnection.Disconnect
TDconnection.logout
TDconnection.ReleaseConnection
Set TDconnection = Nothing
End Function

Related

Wildcards/patterns with .Tables("PARA") when executing RFC INST_EXECUTE_REPORT

I'm using Excel and VBA to get SAP to download data from SAP through RFC using INST_EXECUTE_REPORT.
It works like a charm when I have specific input parameters. I just build up .Tables("PARA") with the screen name of the parameter and the desired value. I can even use this method for date ranges.
The challenge is when I don't know exactly the input parameters. For example, I wanted to identify all internal orders with a specific text in the description, e.g. CODE40.
Is there any way to use wildcards with INST_EXECUTE_REPORT? When the program passed into INST_EXECUTE_REPORT is executed normally as a transaction on screen, I can set the parameter to *CODE40* and SAP automatically applies a wildcard search. But I can't get that to work with VBA.
I can simulate using wildcards when accessing individual tables with BBP_RFC_READ_TABLE by using LIKE statements in the selection option, but I need a similar functionality for whole reports, not individual tables.
Can anyone help?
Best regards,
The code I'm using is as follows:
Set ObjR3_EXECUTE_REPORT = ObjR3.Add("INST_EXECUTE_REPORT")
With ObjR3_EXECUTE_REPORT
Set ObjR3_EXECUTE_REPORT_Name = .Exports("PROGRAM")
Set ObjR3_EXECUTE_REPORT_Para = .Tables("PARA")
Set ObjR3_EXECUTE_REPORT_Result = .Tables("RESULT_TAB")
Set ObjR3_EXECUTE_REPORT_Output = .Tables("OUTPUT_TAB")
End With
ObjR3_EXECUTE_REPORT_Name.Value = ReportName
'Build up the table with the fields to be selected
f = 1
For a = LBound(aParameters) To UBound(aParameters)
aParameterPair = aParameters(a)
aParameterInput = aParameterPair(UBound(aParameterPair))
sParameterName = aParameterPair(LBound(aParameterPair))
For c = LBound(aParameterInput) To UBound(aParameterInput)
sParameterInput = aParameterInput(c)
ObjR3_EXECUTE_REPORT_Para.AppendRow
ObjR3_EXECUTE_REPORT_Para(f, "PARA_NAME") = sParameterName
ObjR3_EXECUTE_REPORT_Para(f, "PARA_VALUE") = sParameterInput
Debug.Print sParameterName & " " & sParameterInput
f = f + 1
Next c
Next a

Find SAP GUI session opened for given SAP system

First I want to check via VBA, before I do some transactions in SAP GUI, if a connection is already open. I am not able to login a second time, so I need to stay in the same connection.
Secondly I want to open another session. The second problem has been solved, if I assume SAP GUI is already open. But I don't know it for sure. So I need to find a way to access the current SAPGUI and Application and Connection, if they exist. If not, the standard code of If Not IsObject(SAPGUI) Then… is fine. But how do I define these variables correctly to check, if they are „filled“ Objects or not?
Thanks for help!
Based on a script by S. Schnell you can use the follwing function to find a free session
Function findGuiSession(ByVal sapSID As String, Optional tCode As String) As SAPFEWSELib.GuiSession
' this will find a free session using the systemnam resp. SID
' and optional one can also supply a transaction to
Dim CollCon As SAPFEWSELib.GuiComponentCollection
Dim CollSes As SAPFEWSELib.GuiComponentCollection
Dim guiCon As SAPFEWSELib.GuiConnection
Dim guiSes As SAPFEWSELib.GuiSession
Dim guiSesInfo As SAPFEWSELib.GuiSessionInfo
Dim i As Long, j As Long
Dim SID As String, transaction As String
'On Error GoTo EH
Dim guiApplication As SAPFEWSELib.guiApplication
Set guiApplication = getGuiApplication
If guiApplication Is Nothing Then
Exit Function
End If
Set CollCon = guiApplication.Connections
If Not IsObject(CollCon) Then
Exit Function
End If
' Loop through all existing connections
For i = 0 To CollCon.Count() - 1
Set guiCon = guiApplication.Children(CLng(i))
If Not IsObject(guiCon) Then
Exit Function
End If
Set CollSes = guiCon.Sessions
If Not IsObject(CollSes) Then
Exit Function
End If
' Now loop through all existing sessions
For j = 0 To CollSes.Count() - 1
Set guiSes = guiCon.Children(CLng(j))
If Not IsObject(guiSes) Then
Exit Function
End If
If guiSes.Busy = vbFalse Then
Set guiSesInfo = guiSes.Info
If guiSesInfo.user = "" Or guiSesInfo.user = "SAPSYS" Then
' Logon Screen - cannot be used
Else
If IsObject(guiSesInfo) Then
SID = guiSesInfo.SystemName()
transaction = guiSesInfo.transaction()
' Take the first one - In case one could also use the transactionaction addtionally
If Len(tCode) = 0 Then
If SID = sapSID Then
Set findGuiSession = guiSes
'FindSession = True
Exit Function
End If
Else
If SID = sapSID And transaction = tCode Then
Set findGuiSession = guiSes
'FindSession = True
Exit Function
End If
End If
End If
End If
End If
Next
Next
Exit Function
'EH:
End Function
Function getGuiApplication() As SAPFEWSELib.guiApplication
On Error GoTo EH
Set getGuiApplication = GetObject("SAPGUI").GetScriptingEngine
EH:
End Function
For this code to run you need to add a reference to the SAP library, described here
The following piece of code uses the above function to connect to a system with the name P11, starts the transaction MB52 and downloads the result in a Excel file
Option Explicit
Sub getMB52_data()
Dim guiSes As SAPFEWSELib.GuiSession
Set guiSes = getGuiSession("P11")
If Not guiSes Is Nothing Then
With guiSes
.StartTransaction "MB52"
.FindById("wnd[0]/usr/ctxtMATNR-LOW").Text = "<MATNR_LOW<" ' replace with a material nr
.FindById("wnd[0]/usr/ctxtMATNR-HIGH").Text = "<MATNR_HIGH<" ' replace with a material nr
.FindById("wnd[0]/usr/ctxtWERKS-LOW").Text = "<WERKS>" ' replace wiht a plant
.FindById("wnd[0]/tbar[1]/btn[8]").Press
.FindById("wnd[0]/tbar[0]/okcd").Text = "&XXL"
.FindById("wnd[0]/tbar[0]/btn[0]").Press
.FindById("wnd[1]/tbar[0]/btn[0]").Press
.FindById("wnd[1]/usr/ctxtDY_PATH").Text = "<xlPath>" ' Pathname
.FindById("wnd[1]/usr/ctxtDY_FILENAME").Text = "<xlFile>" ' filename
.FindById("wnd[1]/tbar[0]/btn[11]").Press
End With
Else
MsgBox "No free SAP Session", vbOKOnly + vbInformation, "SAP Verbindung"
End If
End Sub
Function getGuiSession(sapSID As String, Optional tCode As String) As SAPFEWSELib.GuiSession
Dim guiApp As SAPFEWSELib.guiApplication
Set guiApp = getGuiApplication
If Not guiApp Is Nothing Then
Set getGuiSession = findGuiSession(sapSID, tCode)
End If
End Function
Additonal remarks: (hopefully answering some questions in the comments)
Gui Connection: A GuiConnection represents the connection between SAP GUI and an application server. Connections can be opened from SAP Logon or from GuiApplication’s openConnection and openConnectionByConnectionString
methods
So, in other words a gui connection is a kind of login to an SAP system. And usually you have more than one SAP system in your organization. If you follow the guidelines you have a DEV, QUAL and PROD for a given system environment. Each of this system is identifid by a SID
What is SID?
SID is a unique identification code for every R/3 installation (SAP system) consisting of a database server & several application servers. SID stands for SAP System Identification. SAPSID — a three-character code such as C11, PRD, E56, etc.)
An SID is unique within the organization. Usually SAP licence only allows a user to login to a productive system only once, i.e. you cannot use the same user on different computers and you cannot even login to a SAP system with the same user on the same computer twice.
Having said that: One might be tempted to use guiApplication.Children(0) instead of looping through all connections as done in findGuiSession. And this will work as long as you can make sure that you are only logged on to one SAP system and it is the right one. But in my experience this is often not the case.
The parameter SID in findGuiSession tells the function which system to look for. As written above SID is unique and therefore identfies the system you want to use.
Using tCode in findGuiSession is optional and just forces the user to have a session in place with a given tCode already started. I use this very seldom.
OpenConnection: If you open a connection with the function OpenConnection("<SYSTEM>") you can, of course, use the returned object in order to work with it. But this only does a logon to the system if you have a kind of single sign on in your organization in place. Otherwise you have to provide logon credentials. I do not use this because I do not want to take care of this. And it also can happen that a password change is requested during the logon and I sure do not want to script this.
Example code
Rem Open a connection in synchronous mode
Set Connection = Application.OpenConnection( "U9C [PUBLIC]", True)
Set Session = Connection.Children(0)
Rem Do something: Either fill out the login screen
Rem or in case of Single-Sign-On start a transaction.
Session.SendCommand( "/nbibs")

Extract file names from a File Explorer search into Excel

This has been bugging me for while as I feel I have few pieces of the puzzle but I cant put them all together
So my goal is to be able to search all .pdfs in a given location for a keyword or phrase within the content of the files, not the filename, and then use the results of the search to populate an excel spreadsheet.
Before we start, I know that this easy to do using the Acrobat Pro API, but my company are not going to pay for licences for everyone so that this one macro will work.
The windows file explorer search accepts advanced query syntax and will search inside the contents of files assuming that the correct ifilters are enabled. E.g. if you have a word document called doc1.docx and the text inside the document reads "blahblahblah", and you search for "blah" doc1.docx will appear as the result.
As far as I know, this cannot be acheived using the FileSystemObject, but if someone could confirm either way that would be really useful?
I have a simple code that opens an explorer window and searches for a string within the contents of all files in the given location. Once the search has completed I have an explorer window with all the files required listed. How do I take this list and populate an excel with the filenames of these files?
dim eSearch As String
eSearch = "explorer " & Chr$(34) & "search-ms://query=System.Generic.String:" & [search term here] & "&crumb=location:" & [Directory Here] & Chr$(34)
Call Shell (eSearch)
Assuming the location is indexed you can access the catalog directly with ADO (add a reference to Microsoft ActiveX Data Objects 2.x):
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim sql As String
cn.Open "Provider=Search.CollatorDSO;Extended Properties='Application=Windows'"
sql = "SELECT System.ItemNameDisplay, System.ItemPathDisplay FROM SystemIndex WHERE SCOPE='file:C:\look\here' AND System.Kind <> 'folder' AND CONTAINS(System.FileName, '""*.PDF""') AND CONTAINS ('""find this text""')"
rs.Open sql, cn, adOpenForwardOnly, adLockReadOnly
If Not rs.EOF Then
Do While Not rs.EOF
Debug.Print "File: "; rs.Collect(0)
Debug.Print "Path: "; rs.Collect(1)
rs.MoveNext
Loop
End If
Try using the next function, please:
Function GetFilteredFiles(foldPath As String) As Collection
'If using a reference to `Microsoft Internet Controls (ShDocVW.dll)_____________________
'uncomment the next 2 lines and comment the following three (without any reference part)
'Dim ExpWin As SHDocVw.ShellWindows, CurrWin As SHDocVw.InternetExplorer
'Set ExpWin = New SHDocVw.ShellWindows
'_______________________________________________________________________________________
'Without any reference:_____________________________________
Dim ExpWin As Object, CurrWin As Object, objshell As Object
Set objshell = CreateObject("Shell.Application")
Set ExpWin = objshell.Windows
'___________________________________________________________
Dim Result As New Collection, oFolderItems As Object, i As Long
Dim CurrSelFile As String
For Each CurrWin In ExpWin
If Not CurrWin.Document Is Nothing Then
If Not CurrWin.Document.FocusedItem Is Nothing Then
If left(CurrWin.Document.FocusedItem.Path, _
InStrRev(CurrWin.Document.FocusedItem.Path, "\")) = foldPath Then
Set oFolderItems = CurrWin.Document.folder.Items
For i = 0 To oFolderItems.count
On Error Resume Next
If Err.Number <> 0 Then
Err.Clear: On Error GoTo 0
Else
Result.Add oFolderItems.item(CLng(i)).Name
On Error GoTo 0
End If
Next
End If
End If
End If
Next CurrWin
Set GetFilteredFiles = Result
End Function
Like it is, the function works without any reference...
The above function must be called after you executed the search query in your existing code. It can be called in the next (testing) way:
Sub testGetFilteredFiles()
Dim C As Collection, El As Variant
Set C = GetFilteredFiles("C:\Teste VBA Excel\")'use here the folder path you used for searching
For Each El In C
Debug.Print El
Next
End Sub
The above solution iterates between all IExplorer windows and return what is visible there (after filtering) for the folder you initially used to search.
You can manually test it, searching for something in a specific folder and then call the function with that specific folder path as argument ("\" backslash at the end...).
I've forgotten everything I ever knew about VBA, but recently stumbled across an easy way to execute Explorer searches using the Shell.Application COM object. My code is PowerShell, but the COM objects & methods are what's critical. Surely someone here can translate.
This has what I think are several advantages:
The query text is identical to what you wouold type in the Search Bar in Explorer, e.g.'Ext:pdf Content:compressor'
It's easily launched from code and results are easily extracted with code, but SearchResults window is available for visual inspection/review.
With looping & pauses, you can execute a series of searches in the same window.
I think this ability has been sitting there forever, but the MS documentation of the Document object & FilterView method make no mention of how they apply to File Explorer.
I hope others find this useful.
$FolderToSearch = 'c:\Path\To\Folder'
$SearchBoxText = 'ext:pdf Content:compressor'
$Shell = New-Object -ComObject shell.application
### Get handles of currenlty open Explorer Windows
$CurrentWindows = ( $Shell.Windows() | Where FullName -match 'explorer.exe$' ).HWND
$WinCount = $Shell.Windows().Count
$Shell.Open( $FolderToSearch )
Do { Sleep -m 50 } Until ( $Shell.Windows().Count -gt $WinCount )
$WindowToSerch = ( $Shell.Windows() | Where FullName -match 'explorer.exe$' ) | Where { $_.HWND -notIn $CurrentWindows }
$WindowToSearch.Document.FilterView( $SearchBoxText )
Do { Sleep -m 50 } Until ( $WindowToSearch.ReadyState -eq 4 )
### Fully-qualified name:
$FoundFiles = ( $WindowToSearch.Document.Folder.Items() ).Path
### or just the filename:
$FoundFiles = ( $WindowToSearch.Document.Folder.Items() ).Name
### $FoundFIles is an array of strings containing the names.
### The Excel portion I leave to you! :D

How to access SAP using Excel VBA?

I am trying to log on to SAP. The Excel VBA code gives me a popup window confirming my information however when I submit the form it does not take me to a new SAP window.
Additionally is there a way to automate all the popup boxes asking for confirmation on my information? I want this code eventually to run at certain times of the day, and I might not be available to input any data.
Sub login1()
Dim sap As Object
Dim conn As Object
Set sap = CreateObject("SAP.Functions")
Set conn = sap.Connection
conn.System = "System Test Environment"
conn.client = "100"
conn.user = "user"
conn.Password = "password"
conn.Language = "EN"
If conn.logon(0, False) <> True Then
MsgBox "Logon to the SAP system is not possible", vbOKOnly, "Comment"
Else
End If
End Sub
This Macro will never open a SAP Window - it will create an SAP-Object within VBA where you can work with SAP-RFC-Functions. (Reading Data from SAP, Writing Data into SAP)
In your version the SAP connection will be unaccessible after "End Sub". You have to declair the Object outside the sub.
This works silent (without dialog) for me:
Dim sap As Object
Public Function login1() As Boolean
Set sap = CreateObject("SAP.Functions")
sap.Connection.System = "System Test Environment"
sap.Connection.client = "100"
sap.Connection.user = "user"
sap.Connection.Password = "password"
sap.Connection.Language = "EN"
If sap.Connection.logon(0, False) <> True Then
sap.RemoveAll
MsgBox "Logon to the SAP system is not possible", vbOKOnly, "Comment"
Else
login1 = true
End If
End Function
Public Function SAPLogoff()
On Error Resume Next
sap.RemoveAll
sap.Connection.logoff
LoggedOn = False
Set sap = Nothing
'Set conn = Nothing
End Function
Since you want to "open a new SAP Window" you have to make a different approach!
At First try to open the new instance of SAP from the DOS Commandline with "sapshcut":
C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapshcut.exe -system="System Test Environment" -client="100" -user="user" -password="password" -language="EN"
If your SystemName has no Spaces (and I belive so!) then you can write it also like:
C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapshcut.exe -system=SystemTestEnvironment -client=100 -user=user -password=password -language=EN
When this call works with your credentials, then you can transfer it to Excel like this:
Sub login1()
Call Shell("C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapshcut.exe -system=SystemTestEnvironment -client=100 -user=user -password=password -language=EN",vbNormalFocus)
End Sub
You could also add a transaction by adding "-command=your_tcode" to the String.
If your have spaces in the parameters and you could only start it with -system="System Test Environment" from the Commanline, you will have to escape this in Excel with -system="""System Test Environment""" (!)

How to give public access to files under webcontent in lotus domino

I have a domino application with XPages that i want to be public. So, i set in the ACL the "Default" to Depositor level with read public documents option, so as to make it public.
When i want to use an image resource i go to its properties security tab and i enable the "available to public access users" checkbox.
Now, I want to use font-awesome in my application and i have font-awesome's folder with its subfolders and files under webcontent folder.
How can i make them public? (in a non-public app, font-awesome works normally with font-awesome's folder under webcontent folder)
I simply created an agent to set the flag. You can get the code below. I use it for an Angular app that I have added to the NSF.
HTH
/John
Edit:
Code inserted directly here:
Option Public
Option DeclareSub Initialize
Const APP_DIR = “app/”
Const FN_PUBLICACCESS = “$PublicAccess”
Const FLAG_TRUE = “1”
Dim sess As New NotesSession
Dim db As NotesDatabase
Dim nc As NotesNoteCollection
Set db = sess.currentDatabase
Set nc = db.CreateNoteCollection(False)
Call nc.SelectAllDesignElements(True)
Call nc.BuildCollection
Dim d1 As Long
Dim d2 As Long
Dim title As String
Dim flagsExt As String
Dim noteid As String
Dim nextid As String
Dim i As Long
Dim doc As NotesDocument
noteid = nc.Getfirstnoteid()
For i = 1 To nc.Count
‘get the next note ID before removing any notes
nextid = nc.GetNextNoteId(noteid)
Set doc = db.GetDocumentByID(noteid)
title = doc.GetItemValue(“$title”)(0)
flagsExt = doc.GetItemValue(“$flagsExt”)(0)
If LCase(flagsExt) = “w” And Left(LCase(title),Len(APP_DIR)) = LCase(APP_DIR) Then
d1 = d1 + 1
If Not doc.Getitemvalue(FN_PUBLICACCESS)(0) = FLAG_TRUE Then
d2 = d2 + 1
Call doc.replaceItemValue(FN_PUBLICACCESS,FLAG_TRUE)
Call doc.save(True, False)
Print title & ” – set to allow public access read”
End If
End If
noteid = nextid
Next
Print nc.count & ” design elements checked. “ & d1 & ” elements found in ‘” & APP_DIR & “‘ and “ & d2 & ” updated to give public access”
End Sub
They still get registered as design notes inside the NSF (which is why they're picking up the default visibility), so I think the only real option is to run an agent to update their visibility, explicitly. Sven Hasselbach has blogged about this topic a couple times (at least on interacting with items in the WebContent folder, programmatically) and is worth reading. Ultimately, I try to put these sorts of public agnostic, common resources into my Domino /Data/domino/html/ path, so as to have it always public (that path is always publicly visible), and available to be set in a theme .
[Update]
See the link Per Henrik Lausten posted in the comments to the Q for details.
[/Update]

Resources