Checking the folder type - vbscript

I loop through each folder of my Outlook store to check the folder type by retrieving all default folders and comparing their EntryID.
Public Function GetFolderTypeName(objFolder)
Dim objType, objDefaultFolder
'dctValidFolders is a dictionary of default folders type
For Each objType in dctValidFolders
Set objDefaultFolder = objMAPI.GetDefaultFolder(dctValidFolders.Item(objType))
If objFolder.EntryID = objDefaultfolder.EntryID Then
Set objDefaultfolder = Nothing
GetFolderTypeName = objType
Exit Function
End If
Next
End Function
Now, I have a mailbox that has more than one folder of type contacts.
Is there another way to know the folder type?

There was in fact, check
folder.DefaultItemType
This will return an item type , like olMailItem, and depending on that you can "assume" the folder type.

Related

Is there a faster way to get file metadata than by using the shell COM component?

Reading various answers here and elsewhere, I pieced together this bit to get the file metadata that I need:
Public Class windows_metadata_helper
Public Shared shell As New Shell32.Shell
Public Shared indices_of_interest As New Dictionary(Of Integer, String)
Public Shared path_index As Integer
Shared Sub New()
'snipped long piece code for figuring out the indices of the attributes that I need, they are stored in indices_of_interest, for example 0:Name
End Sub
Public Shared Function get_interesting_data(path) As Dictionary(Of String, String)
Dim fi As New IO.FileInfo(path)
Dim f_dir = shell.NameSpace(fi.DirectoryName)
Dim data As New Dictionary(Of String, String)
For Each item In f_dir.Items()
If f_dir.GetDetailsOf(item, path_index) = fi.FullName Then
For Each kvp In indices_of_interest
Dim val = f_dir.GetDetailsOf(item, kvp.Key)
If Not String.IsNullOrEmpty(val) Then data.Add(kvp.Value, val)
Next
Exit For
End If
Next
Return data
End Function
End Class
Its not the most efficient code in the world, namely getting the path attribute of each file in the directory to identify the file I'm actually interested in. Optimizing this to only read the path attribute of each file once makes it around 50% faster (tested by letting it take the first file it finds whether its the right one or not) but regardless, its far slower than expected.
It needs to fetch 24 attributes from each file and it needs to find around 20k files from within ~100k, currently this takes an entire hour.
Profiling tells me that CPU is the bottleneck and whatever is taking up the cycles I can't see since its 99% inside the Shell32.Folder.GetDetailsOf method.
Is there a faster way to get the metadata? Answer doesn't have to be vb or .net specific.
Since you are seeking maximum speed, I suggest that you enable Option Strict for your code and make the necessary modifications that will be suggested by the IDE. This will eliminate unnecessary type conversions.
For instance,
Public Shared Function get_interesting_data(path) As Dictionary(Of String, String)
should be:
Public Shared Function get_interesting_data(path As String) As Dictionary(Of String, String)
Instead of enumerating the Shell32.Folder.Items collection, use the Shell32.Folder.ParseName Method to directly retrieve a FolderItem object. This object can be cast to a Shell32.ShellFolderItem that will allow using the ShellFolderItem.ExtendedProperty method.
There are two ways to specify a property. The first is to assign the
property's well-known name, such as "Author" or "Date", to sPropName.
However, each property is a member of a Component Object Model (COM)
property set and can also be identified by specifying its format ID
(FMTID) and property ID (PID). An FMTID is a GUID that identifies the
property set, and a PID is an integer that identifies a particular
property within the property set.
Specifying a property by its FMTID/PID values is usually more
efficient than using its name. To use a property's FMTID/PID values
with ExtendedProperty, they must be combined into an SCID. An SCID is
a string that contains the FMTID/PID values in the form "FMTID**PID",
where the FMTID is the string form of the property set's GUID. For
example, the SCID of the summary information property set's author
property is "{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 4".
Many FMTID/PID values can be found under links presented at Windows Properties.
You can find the full property table here (scroll down).
Putting this together for some selected properties:
Public Shared Function get_interesting_data(path As String) As Dictionary(Of String, String)
Dim fi As New IO.FileInfo(path)
Dim f_dir As Shell32.Folder = shell.NameSpace(fi.DirectoryName)
' instead of enumerating f_dir.Items to find the file of interest
' directly retrieve the item reference
Dim item As Shell32.ShellFolderItem = DirectCast(f_dir.ParseName(fi.Name), Shell32.ShellFolderItem)
Dim scid_Bitrate As String = "{64440490-4C8B-11D1-8B70-080036B11A03} 4" ' Audio: System.Audio.EncodingBitrate
Dim scid_Title As String = "{F29F85E0 - 4.0FF9-1068-AB91-08002B27B3D9} 2" ' Core: System.Title
Dim scid_Created As String = "{B725F130-47EF-101A-A5F1-02608C9EEBAC} 15" ' Core: System.DateCreated
Dim scid_Copyright As String = "{64440492-4C8B-11D1-8B70-080036B11A03} 11" ' Core: System.Copyright
Dim scid_Publisher As String = "{64440492-4C8B-11D1-8B70-080036B11A03} 30" ' Media: System.Media.Publisher
Dim scid_FullDetails As String = "{C9944A21-A406-48FE-8225-AEC7E24C211B} 2" ' PropList: System.PropList.FullDetails
Dim bitrate As Object = item.ExtendedProperty(scid_Bitrate)
Dim title As Object = item.ExtendedProperty(scid_Title)
Dim created As Object = item.ExtendedProperty(scid_Created)
Dim copyright As Object = item.ExtendedProperty(scid_Copyright)
Dim publisher As Object = item.ExtendedProperty(scid_Publisher)
Dim fullDetails As Object = item.ExtendedProperty(scid_FullDetails)
Dim data As New Dictionary(Of String, String)
' save the retrieved properties
Return data
End Function
I do not know if this technique of retrieving the properties is faster than you have currently using GetDetailsOf, but the other changes should make some improvement.

Lists in VBscript return object

I'm writing a vbscript function that looks something like this:
Public Function fnGetXLSFileCount()
Dim fso, src, folder, file, fileList
Set fileList = CreateObject("System.Collections.ArrayList")
Set fso = CreateObject("Scripting.FileSystemObject")
src = "\\myserver\myfolder"
Set folder = fso.GetFolder(src)
For Each file In folder.files
If LCase(fso.GetExtensionName(file)) = "xlsx" Then
fileList.Add file.name
End If
Next
Set fnGetXLSFileCount = fileList
End Function
As you can see I'm creating an ArrayList and then adding all the names of excel files that exist in a specified folder.
I then call this function and use the Set operator to specify that I'm expecting an object to be returned.
Set XLSFileList = fnGetXLSFileCount
When I check the count on the object it seems to be correct.
When I try to pull the names out there is nothing there. What am I doing incorrectly here?
For each file in XLSFileList
name = file.Item(0)
Next
The For Each loop already enumerates the items of the collection. And since you assign just the names to the collection you simply use the loop variable to get the name:
For Each file In XLSFileList
name = file
Next
The Item property can be used to directly access a specific item from the collection:
WScript.Echo XLSFileList.Item(0)

Dynamically Rename Shared OR object names

As per the naming convention we are following, we need to rename every object to its standard name.
One such convention is to replace space between with ‘_’
eg. Object name ->Object_name
Is there any way to perform it dynamically using lines of code.?
What you can do , Export the repository to the XML . Then Using the XML dom Object you can navigate to each Node.Each Node will have a Name Attribute .Then you can check there is a space if it is You can change the logical name of it .This will change the Object Repository Names .
But you need do similar king of change in your QTPscript to get reflected .
Export the OR to xml file and use the following line of code.
And use the xml generated to import OR back to QTP.
This is specific to SAP GUI
Function ModifyORXML(inputFilepath,outputFilepath)
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.Async = "False"
xmlDoc.Load(inputFilepath)
Set xmlNodeList = xmlDoc.getElementsByTagName("qtpRep:Object")
num = xmlNodeList.length
For each x in xmlNodeList
AttName=x.getattribute("Name")
If x.getattribute("Class")="SAPGuiButton" Then
tmp=Split(AttName," ",-1,1)
AttName=tmp(0)
End If
AttName=Replace(AttName,Chr(34)," ")
AttName=Replace(AttName,")"," ")
AttName=Trim(AttName)
oldAttName=AttName
AttName=Replace(AttName,":"," ")
AttName=Trim(AttName)
AttName=Replace(AttName," ","_")
AttName=Replace(AttName," __","_",1,-1,1)
x.Attributes.getNamedItem("Name").Text = AttName
Next
xmlDoc.Save outputFilepath
End Function

How to store a changing webpage in a variable?

My script automates the room booking process at my school for group projects. I have created an automatic log-in script which works fine. Now I would like to access different elements from the loaded page (check boxes, radio buttons...).
How can I save various elements from the page that I have logged-in into and perform certain actions on them?
Func SignIn()
Global $window = _IECreate("https://roombooking.au.dk/classes/Login.aspx? ReturnUrl=%2fclasses%2fbook.aspx")
_IELoadWait($window)
If #error Then Return
WinSetState("[ACTIVE]", "", #SW_MAXIMIZE)
Local $username = _IEGetObjByName($window,"ctl00$Main$UsernameBox")
Local $password = _IEGetObjByName($window,"ctl00$Main$PasswordBox")
Local $button = _IEGetObjByName($window, "ctl00$Main$LoginBtn")
_IEFormElementSetValue($username,"abc")
_IEFormElementSetValue($password,"123")
_IEAction ($button, "click")
EndFunc
Func Room()
Local $SelectRoom = _IEGetObjByName(**???**,"ctl00$Main$ChangeReqsBtn")
_IELoadWait($bwindow)
_IEAction($s526,"click")
EndFunc
From the Help File:
#include <IE.au3>
_IEGetObjByName ( ByRef $oObject, $sName [, $iIndex = 0] )
$oObject Object variable of an InternetExplorer.Application, Window or Frame object
$sName Specifies name of the object you wish to match
$iIndex If name occurs more than once, specifies instance by 0-based index
0 (Default) or positive integer returns an indexed instance
-1 returns a collection of the specified objects
In your case the code will be something like:
Local $SelectRoom =
_IEGetObjByName($window,"ctl00$Main$ChangeReqsBtn")
AutoIt offers many different approaches to HTML document retrieval. Without providing concerning source code it can only be guessed.
HTML source of document is returned by _IEDocReadHTML() (assuming you're using IE.au3 UDF). Example:
#include <IE.au3>
Global Const $oIE = _IECreate('http://www.google.com/')
Global Const $sDocHTML = _IEDocReadHTML($oIE)
_IEQuit($oIE)
ConsoleWrite($sDocHTML & #LF)
Exit 0
Mentioned UDF contains functions to set values to form elements (lookup _IEForm...() in AutoIt's user defined function reference).

Issue with opening the right path for file dialog

i am using vba access 2010 and have a simple form, a button control. the idea is to create a folder and after which use the filedialog to open up the folder i just created. i am able to create the folder, but how do i open up to the path i just created? below will be the code i have, will really really appreciate it if anyone can help. thanks in advance
Option Compare Database
Private Sub Command0_Click()
Dim Foldername As String
Foldername = "\\server\Instructions\"
MkDir ("C:\Users\Stanley\Desktop\New folder\123")
setProfilePicture
End Sub
'----------------------image path setting---------------------
Private Sub setProfilePicture()
'Declare a variable as a FileDialog object.
Dim fd As FileDialog
'Create a FileDialog object as a File Picker dialog box.
Set fd = Application.FileDialog(msoFileDialogFilePicker)
'Declare a variable to contain the path
'of each selected item. Even though the path is a String,
'the variable must be a Variant because For Each...Next
'routines only work with Variants and Objects.
Dim vrtSelectedItem As Variant
'Use a With...End With block to reference the FileDialog object.
With fd
'Change the contents of the Files of Type list.
'Empty the list by clearing the FileDialogFilters collection.
.Filters.Clear
'Add a filter that includes all files.
.Filters.Add "All files", "*.*"
'Add a filter that includes GIF and JPEG images and make it the first item in the list.
.Filters.Add "Images", "*.gif; *.jpg; *.jpeg", 1
'Use the Show method to display the File Picker dialog box and return the user's action.
'The user pressed the action button.
If .Show = -1 Then
'Step through each String in the FileDialogSelectedItems collection.
For Each vrtSelectedItem In .SelectedItems
'vrtSelectedItem is a String that contains the path of each selected item.
'You can use any file I/O functions that you want to work with this path.
'This example simply displays the path in a message box.
'MsgBox "Path name: " & vrtSelectedItem
Me.ImagePerson.Picture = vrtSelectedItem
'Me.TextboxPersonFilepath.Value = "File path: " & vrtSelectedItem
Next vrtSelectedItem
'The user pressed Cancel.
Else
End If
End With
'Set the object variable to Nothing.
Set fd = Nothing
End Sub
'-----------------end of image path setting--------------
Pass it as a variable.
In your Command0_Click sub, set your directory as a variable, like
X = "MyPath To My Folder"
Then, call setProfilePicture(X)
In setProfilePicture, set it up like:
Private Sub setProfilePicture(MyDir as String)
Then MyDir is now the path to your folder, and you can use it as a variable in your sub

Resources