ComboBox list: How can I execute code when a certain item in a combo box is clicked or highlighted? - combobox

I'm building a handy application for myself. It's a program that contains links to others programs, so that I can start them from a central place. I already have the design, but I want my application to start a program when an item is clicked in the combo box. For example: Microsoft Office Word is an item in that list, when I click on it, I want it to launch Microsoft Office Word. How can I do that? Arready tried the following:
Private Sub programCombo_Click()
'If programCombo.List(1) = "Word" Then
'Shell "C:\Program Files\Everything\Everything.exe", vbNormalFocus
'End If
Select Case UCase(programCombo.Text)
Case "Word"
Shell "C:\Program Files (x86)\Microsoft Office\Office16\WINWORD.EXE", vbNormalFocus
Case "Excel"
Shell "C:\Program Files (x86)\Microsoft Office\Office16\Excel.EXE", vbNormalFocus
End Select
End Sub
But this doesn't do anything. I sort of made it work, but only if I edit the "Text" property of the Combo box. When I change "programCombo.List(1)"to item 2 in the combo box list, it doesn't do anything.
I know I can do all of this with buttons, but if I do that, it will be a big, ugly and clumsy program.

You stated in your description what needs to happen - start a program when an item is clicked - so the solution is to respond to a Click event on the combobox. The following code is a basic example of what I am talking about.
Option Explicit
Private Sub Form_Load()
programCombo.AddItem "Word"
programCombo.AddItem "Excel"
End Sub
Private Sub programCombo_Click()
Select Case UCase(programCombo.Text)
Case "WORD"
Shell "C:\Program Files (x86)\Microsoft Office\Office16\WINWORD.EXE", vbNormalFocus
Case "EXCEL"
'shell excel
End Select
End Sub

I figured it out. I was being a bit dumb. UCase converts it to uppercase, and I used "Word" and not "WORD". Good thing I searched for UCase. Thanks for the suggestions guys.
I'm now gonna crawl up in a corner and cry for being so dumb.

Related

Get Msgbox 3mins later after clicking a commandbutton1 vba

I am really stuck with one of my project. I need to get msgbox appearing 3mins later once clicked on commandbutton1.
I have a button which copies the text "I will be back in 3minutes" now I need to have a pop msg after 3minutes reminding user with popmsg "your time is up"
I tested 10 seconds interval, and it worked.
Private Sub CommandButton1_Click()
'any previous stuff
Application.OnTime Now + TimeValue("00:00:10"), "RemindMe"
End Sub
The following subroutine is in a module.
Sub RemindMe()
MsgBox "your time is up!"
End Sub
Meanwhile, the Excel window doesn't get frozen, you can still operate on the worksheet.

Open the latest file

I have an Access form with the drawing number D-A1ER-1378-1601-0 listed which is also stored in a file folder.
I use the code below to open the pdf drawing, which works fine.
Public Sub OpenDWG()
Dim strFile As String
Dim PathPDF As String
On Error GoTo Failure
PathPDF = DLookup("[FilePath]", "[SettingsDrawingFilePathTbl]", "ID = 4")
strFile = PathPDF & "\" & Screen.ActiveControl & ".pdf"
If Len(Dir(strFile)) Then
FollowHyperlink strFile
Else
MsgBox "No Document found for this Drawing Number, check Engineering Drawing Search File path in the Settings Tab and / drawing download files"
End If
Exit Sub
Failure:
MsgBox Err.Description
Err.Clear
End Sub
How do I adjust the strfile name
strFile = PathPDF & "\" & Screen.ActiveControl & ".pdf"
to get the form to open only the most recent file when a new version of the drawing is dropped into the folder. ie D-A1ER-1378-1601-0(2) will be the newest revision.
I would like to add a comment, but I don't have enough points ot comment.
I think that you can use the Dir function to get all files beginning with the same characters, or with wild cards, etc. I'll have to look into how exactly to do this. You could populate an array with these, and use code to scan the array to determine the latest file. Or you could populate a temporary table amd then use the table contents as the course to a combo box to have the user select the desired file, sorted with the latest one on top.
If I get a chance, I'll conjure up some sample code an post it.

Find and replace in text files using AppleScript

I am trying to write an applescript which will run via a launch agent. What the script needs to do is edit a user preference plist file so that default save locations are specific to that user. I am aware that this can be done by just setting "~/documents" as the location in the template plist. But Premier Pro for example also needs to write scratch files to a local drive. For simplicity I would like each user to have these put in a locations based on their username. This script will only need to run if the local profile has just been created from a template at first log on.
I have started by using some sample code found on this site and just making a simple test below. This test should edit a txt file and replace one word with another. This script is currently not working. When tested it opens up test.txt in TextEdit but does nothing more. No errors are displayed either.
Thank you in advance
John.
replaceText("replace this", "replace with this", "/Volumes/USB_Drive/test.txt")
on replaceText(search_string, replacement_text, this_document)
tell application "TextEdit"
open this_document
set AppleScript's text item delimiters to the search_string
set this_text to the text of the front document as list
set AppleScript's text item delimiters to the replacement_text
set the text of the front document to (this_text as string)
close this_document saving yes
end tell
end replaceText
Here an version that doesn't need text edit. It will read the file in utf-8 encoding, update it's contents and store that back into the file as utf-8 encoded text. The reason I use an try block around writing the file is that there will be an error if another application has the file open with read permission at the same time. The considering case block can be wrapped around the set ti to every text item of theContent if you want the search and replace case sensitive. There is no need for this to be active when you replace the string, only for finding it.
set stringToFind to "replace that"
set stringToReplace to "with this"
set theFile to choose file
set theContent to read theFile as «class utf8»
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, stringToFind}
set ti to every text item of theContent
set AppleScript's text item delimiters to stringToReplace
set newContent to ti as string
set AppleScript's text item delimiters to oldTID
try
set fd to open for access theFile with write permission
set eof of fd to 0
write newContent to fd as «class utf8»
close access fd
on error
close access theFile
end try
Well, yes, as #dj_bazzie_wazzie points out, you really don't need a text editor for this, you can use the terminal and do something like:
perl -pi -e 's/old text/new text/g' /path/to/theFile.plist
which of course you can use in AppleScript with the powerful do shell script command:
do shell script "perl -pi -e 's/" & search_string & "/" & replacement_text & "/g' " & quoted form of (POSIX path of file_path)
--assuming file_path is a variable with Mac-style (colon-separated) file path.
Modified from http://discussions.apple.com/message/20542594#20542594, the handler below does what you want. I made a few changes and added your variables. A few notes: (1) the 'my' before the handler call makes sure it is seen as the script's handler and not something TextEdit should interpret 'internally' (because it is in a tell block); (2) 'considering case' makes the handler case sensitive, which I assume you want; (3) You might consider something like TextWrangler, which has robust and feature-rich AppleScript support, and includes text replacement in its AS dictionary, as does Smile, a fantastic Script Editor (which can work with text, and formats plist files nicely).
tell application "TextEdit"
set workingWin to open this_document
set this_text to the text of the workingWin
set the text of the workingWin to (my replaceText(this_text, search_string, replacement_text))
close workingWin saving yes
end tell
to replaceText(someText, oldItem, newItem)
(*
replace all occurances of oldItem with newItem
parameters - someText [text]: the text containing the item(s) to change
oldItem [text, list of text]: the item to be replaced
newItem [text]: the item to replace with
returns [text]: the text with the item(s) replaced
*)
considering case
set {tempTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, oldItem}
try
set {itemList, AppleScript's text item delimiters} to {text items of someText, newItem}
set {someText, AppleScript's text item delimiters} to {itemList as text, tempTID}
on error errorMessage number errorNumber -- oops
set AppleScript's text item delimiters to tempTID
error errorMessage number errorNumber -- pass it on
end try
end considering
return someText
end replaceText

How to detect files (even in subfolders) with a specific extension and open them?

I'm trying to make a droplet applscript app. It should do:
when a folder is dropped it should "scan" the folder,its subfolders and files
every file with a specific extension (such as: .txt" should be opened in an program and something should be done
that's all
I get this error when I detected the right file and if it is trying to open it (the app won't be started- before that I get this error and the script cancels):class nmxt of alias "the path to the file" could not be read
Currently my script:
on open {input}
set theFiles to (getFilesRecursively(input, "plhs"))
repeat with oneFile in theFiles
if name extension of oneFile is "plhs" then
tell application "Applic"
open oneFile
activate
tell application "System Events"
tell process "Applic"
click menu item "Save" of menu 1 of menu bar item "File" of menu bar 1
end tell
end tell
end tell
end if
end repeat
end open
on getFilesRecursively(fContainer, fExt)
tell application "Finder"
set recursiveFileList to entire contents of fContainer as alias list
set resultFileList to {}
repeat with aFile in recursiveFileList
if name extension of aFile contains fExt then
set resultFileList to resultFileList & aFile
end if
end repeat
end tell
return resultFileList
end getFilesRecursively
Here is a germinal script that should get you going:
property kTargetFileExtension : "txt"
property pValidFileList : {}
on open of theFiles -- Executed when files or folders are dropped on the script
set fileCount to (get count of items in theFiles)
repeat with thisFile from 1 to fileCount
set theFile to item thisFile of theFiles
tell application "System Events"
set file_info to get info for theFile
end tell
if visible of file_info is true then -- check for the file extension here as well
if folder of file_info is true then
my createList(theFile)
else
set fileName to name of file_info
set targetFileFound to isTargetFile(fileName, kTargetFileExtension) of me
if (targetFileFound) then
set end of pValidFileList to theFile
end if
end if
end if
end repeat
display dialog "pValidFileList = " & pValidFileList
(* do something with your files listed in pValidFileList here *)
end open
on createList(mSource_folder)
set item_list to ""
tell application "System Events"
set item_list to get the name of every disk item of (mSource_folder as alias)
end tell
set item_count to (get count of items in item_list)
repeat with i from 1 to item_count
set the_properties to ""
set the_item to item i of the item_list
set fileName to the_item
set the_item to ((mSource_folder & the_item) as string) as alias
tell application "System Events"
set file_info to get info for the_item
end tell
if visible of file_info is true then -- check for the file extension here as well
if folder of file_info is true then
my createList(the_item)
else
set targetFileFound to isTargetFile(fileName, kTargetFileExtension) of me
if (targetFileFound) then
set end of pValidFileList to the_item
end if
end if
end if
end repeat
end createList
on isTargetFile(theFilename, theTargetExtension) -- (string, string) as boolean
set AppleScript's text item delimiters to "."
set fileNameList to every text item of theFilename
set AppleScript's text item delimiters to ""
try
set theFileExtension to item 2 of fileNameList as string
on error
return false
end try
if theFileExtension is theTargetExtension then
return true
end if
return false
end isTargetFile
A couple things to note:
System Events is the current best practice for getting lists and information about files. Just asking for the entire contents is faster but known to be unreliable. This method of crawling manually is slower but there is no doubt you will be getting the files you need.
isTargetFile actually just works with the filename as a string, as opposed to relying on the system to give the information. Six of one, half dozen of the other if you ask me, but this does reduce the number of calls to the system, so I imagine it makes this a bit faster.
I also tend to add an on run {} block to these things to allow for manual selection of a folder. Doing so also facilitates testing.
How to use:
Save the script as an application, and you should get a droplet (the Applescript application icon with the arrow pointing down).
on open of theFiles is the equivalent of main(). You can drop any combination of files and folders onto the droplet, and it will handle the rest. It ends up with a list of target files that you can then loop through for processing. I will leave it as an exercise for you to add in that bit.
To customize the target, change the string in the first line, property kTargetFileExtension : "txt", to whatever extension you are looking for. This can also be changed to an array—property kTargetFileExtension : {"txt", "rtf", "doc} for example—but you will also need to update isTargetFile(theFilename, theTargetExtension) to loop through those as well.
Beyond that, this just works. Right now, it will gather a list of txt files for processing.
Add salt to taste.

MS Access - open a form taking a field value from a previous form

I have a form in an MS Access database which lists all the landowners consulted with for a new electricity line. At the end of each row is a button which opens another form, showing the details of all consultation, offers made etc.
I am trying to use vb in MS Access to take the contactID and automatically put it in a field in the details form, so that landowner's consultation details will pop up automatically. I am not a vb programmer at all (I have a comp sci degree mostly in Java and I'm currently working as a GIS analyst but it's a small company so I've been asked to get an Access database working).
I want to say
[detailsForm]![contactID] = [landownerlist]![ID]
in a way that vb and access will be happy with. Then I can see if I'm on the right track and if it will actually work! What I have above does not actually work. It won't compile.
From Kaliana
If you wish to open a form to a new record and to set the ID there, you can use Openargs, an argument of Openform:
DoCmd.OpenForm "FormName",,,,acFormAdd,,Me.ID
The opened form would also need some code:
If Me.Openargs<>vbNullstring Then
Me.Id = Me.Openargs
End If
It is also possible to find:
Forms!LandownersList.Recordset.FindFirst "ID=" & Me.ID
or fill in a value:
Forms!LandownersList!Id = Me.ID
on the form being opened from the calling form.
You may want to look into the code that is behind these buttons. If you are using a docmd.openform you can set the 4th Setting to a where clause on openning the next form.
DoCmd.OpenForm "OpenFormName", acNormal, , "[contactID] = " _
& [detailsForm]![contactID] , acFormEdit, acWindowNormal
This assumes contact ID is numeric and doesn't require any quotes.
Using open args is the generally accepted solution, as alluded to by others. This just falls under the category of "For you edification":) One of the problems with using open args is that unless you are careful with your comments it's easy to forget what they were supposed to mean. Were you passing more than one? Which is which? How did I do it here? How did I do it there etc. For my own money, I standardized to this (below) so I can always pass more than one argument without fear, and when I review my code a year from now, I can still see what's what without a huge hassle:
Option Explicit
'Example use: DoCmd.OpenForm "Example", OpenArgs:="Some Filter|True"
Public Enum eForm1Args
eFilter = 0
eIsSpecial = 1
End Enum
Private m_strArgs() As String
Public Property Get Args(ByVal eForm1Args As eForm1Args) As String
Args = m_strArgs(eForm1Args)
End Property
Private Sub Form_Open(Cancel As Integer)
m_strArgs = Split(Nz(Me.OpenArgs, vbNullString), "|")
If LenB(Me.Args(eFilter)) Then Me.Filter = Me.Args(eFilter)
End Sub
Private Sub Command1_Click()
If LCase$(Me.Args(eIsSpecial)) = "true" Then
'Do something special
End If
End Sub
As previously posted OpenArgs is great for this. One trick I have learned is that it is easy to pass in multiple parameters if required as a delimited string (comma for example), the target form can then access these values using the Split() function thus:
StringArrayVariable()= Split(me.OpenArgs,",")
Me.textbox= StringArrayVariable(0)
Me.textbox1= StringArrayVariable(1)
etc.
This is air code so check out the helpfile for Split().
It is also possible to pass objects in OpenArgs as well, it requires some manual memory pointer manipulation and I don't have the code to hand but I'm sure a Google search will find some examples. This technique can cause some random crashes though. Be Warned!

Resources