I am trying to enter the value of cell C4, which is gotten from an input box which assigns the value to the cell, into the search box after submitting at the first page but I am not able to as I keep getting an error 438. Is there something wrong with my codes after the input box?
And is there a way that I can have the codes wait until cell C4 is assigned with the value in the input box then continue with filling in the 2nd page?
Also, I am using Internet Explorer 11, what should my objItem.FullName Like be if I want to use the opened browser to work on?
Option Explicit
Const word1 As String = "C2"
Const word2 As String = "C3"
Const word3 As String = "C4"
Public Sub Test()
Dim objWindow As Object
Dim objIEApp As Object
Dim objShell As Object
Dim objItem As Object
Dim wordthree As String
On Error GoTo Fin
Set objShell = CreateObject("Shell.Application")
Set objWindow = objShell.Windows()
For Each objItem In objWindow
If LCase(objItem.FullName Like "*iexplore*") Then
Set objIEApp = objItem
End If
Next objItem
If objIEApp Is Nothing Then
Set objIEApp = CreateObject("InternetExplorer.Application")
objIEApp.Visible = True
End If
With objIEApp
.Visible = True
.Navigate "google.com"
While Not .ReadyState = 4
DoEvents
Wend
.Document.all.q.Value = Range(word1).Value
'.Document.all.q.Value = Range(word2).Value
.Document.forms(0).submit
End With
3word = InputBox("Enter 3rd word: ")
Range("C4").Value = wordthree
With objIEApp
.Visible = True
While Not .ReadyState = 4
DoEvents
Wend
.Document.all.q.Value = Range(word3).Value
.Document.forms(0).submit
End With
Fin:
If Err.Number <> 0 Then MsgBox "Error: " & _
Err.Number & " " & Err.Description
Set objWindow = Nothing
Set objShell = Nothing
End Sub
The first thing I can spot here is that you're attempting to name your variables starting with a number. In the VB world (VBA, VB.Net etc. all included), this is not valid & your code won't work.
Please see https://msdn.microsoft.com/en-us/library/office/gg264773.aspx for more info on variable naming rules.
Update:
The next thing & reason you're getting the error, is that you need to include a call to exit the method before the error handling routine code is called. Your code above now worked correctly for me with this "exit sub" statement added.
.Document.all.q.Value = Range(word3).Value
.Document.forms(0).submit
End With
**Exit Sub**
Fin:
If Err.Number <> 0 Then MsgBox "Error: " & _
Related
I am new to VBA and obviously I am missing something. My code works for opening a word doc and sending data to it BUT does NOT for an ALREADY OPEN word doc. I keep searching for an answer on how to send info from Excel to an OPEN Word doc/Bookmark and nothing works.
I hope it is okay that I added all the code and the functions called. I really appreciate your help!
What I have so far
Sub ExcelNamesToWordBookmarks()
On Error GoTo ErrorHandler
Dim wrdApp As Object 'Word.Application
Dim wrdDoc As Object 'Word.Document
Dim xlName As Excel.Name
Dim ws As Worksheet
Dim str As String 'cell/name value
Dim cell As Range
Dim celldata As Variant 'added to use in the test
Dim theformat As Variant 'added
Dim BMRange As Object
Dim strPath As String
Dim strFile As String
Dim strPathFile As String
Set wb = ActiveWorkbook
strPath = wb.Path
If strPath = "" Then
MsgBox "Please save your Excel Spreadsheet & try again."
GoTo ErrorExit
End If
'GET FILE & path of Word Doc/Dot
strPathFile = strOpenFilePath 'call a function in MOD1
If strPathFile = "" Then
MsgBox "Please choose a Word Document (DOC*) or Template (DOT*) & try again." 'strPath = Application.TemplatesPath
GoTo ErrorExit
End If
If FileLocked(strPathFile) Then 'Err.Number = 70 if open
'read / write file in use 'do something
'NONE OF THESE WORK
Set wrdApp = GetObject(strPathFile, "Word.Application")
'Set wrdApp = Word.Documents("This is a test doc 2.docx")
'Set wrdApp = GetObject(strPathFile).Application
Else
'all ok 'Create a new Word Session
Set wrdApp = CreateObject("Word.Application")
wrdApp.Visible = True
wrdApp.Activate 'bring word visiable so erros do not get hidden.
'Open document in word
Set wrdDoc = wrdApp.Documents.Open(Filename:=strPathFile) 'Open vs wrdApp.Documents.Add(strPathFile)<=>create new Document1 doc
End If
'Loop through names in the activeworkbook
For Each xlName In wb.Names
If Range(xlName).Cells.Count = 1 Then
celldata = Range(xlName.Value)
'do nothing
Else
For Each cell In Range(xlName)
If str = "" Then
str = cell.Value
Else
str = str & vbCrLf & cell.Value
End If
Next cell
'MsgBox str
celldata = str
End If
'Get format and strip away the spacing, negative color etc etc
'I know this is not right... it works but not best
theformat = Application.Range(xlName).DisplayFormat.NumberFormat
If Len(theformat) > 8 Then
theformat = Left(theformat, 5) 'was 8 but dont need cents
Else
'do nothing for now
End If
If wrdDoc.Bookmarks.Exists(xlName.Name) Then
'Copy the Bookmark's Range.
Set BMRange = wrdDoc.Bookmarks(xlName.Name).Range.Duplicate
BMRange.Text = Format(celldata, theformat)
'Re-insert the bookmark
wrdDoc.Bookmarks.Add xlName.Name, BMRange
End If
Next xlName
'Activate word and display document
With wrdApp
.Selection.Goto What:=1, Which:=2, Name:=1 'PageNumber
.Visible = True
.ActiveWindow.WindowState = wdWindowStateMaximize 'WAS 0 is this needed???
.Activate
End With
GoTo WeAreDone
'Release the Word object to save memory and exit macro
ErrorExit:
MsgBox "Thank you! Bye."
Set wrdDoc = Nothing
Set wrdApp = Nothing
Exit Sub
'Error Handling routine
ErrorHandler:
If Err Then
MsgBox "Error No: " & Err.Number & "; There is a problem"
If Not wrdApp Is Nothing Then
wrdApp.Quit False
End If
Resume ErrorExit
End If
WeAreDone:
Set wrdDoc = Nothing
Set wrdApp = Nothing
End Sub
file picking:
Function strOpenFilePath() As String
Dim intChoice As Integer
Dim iFileSelect As FileDialog 'B
Set iFileSelect = Application.FileDialog(msoFileDialogOpen)
With iFileSelect
.AllowMultiSelect = False 'only allow the user to select one file
.Title = "Please... Select MS-WORD Doc*/Dot* Files"
.Filters.Clear
.Filters.Add "MS-WORD Doc*/Dot* Files", "*.do*"
.InitialView = msoFileDialogViewDetails
End With
'make the file dialog visible to the user
intChoice = Application.FileDialog(msoFileDialogOpen).Show
'determine what choice the user made
If intChoice <> 0 Then
'get the file path selected by the user
strOpenFilePath = Application.FileDialog( _
msoFileDialogOpen).SelectedItems(1)
Else
'nothing yet
End If
End Function
checking if file is open...
Function FileLocked(strFileName As String) As Boolean
On Error Resume Next
' If the file is already opened by another process,
' and the specified type of access is not allowed,
' the Open operation fails and an error occurs.
Open strFileName For Binary Access Read Write Lock Read Write As #1
Close #1
' If an error occurs, the document is currently open.
If Err.Number <> 0 Then
' Display the error number and description.
MsgBox "Function FileLocked Error #" & str(Err.Number) & " - " & Err.Description
FileLocked = True
Err.Clear
End If
End Function
ANSWER BELOW. Backstory... So, after input from you guys and more research I discovered that I needed to set the active word document by using the file selection the user picked and that is then passed via late binding to the sub as an object to process. NOW it works if the word file is not in word OR if it is currently loaded into word AND not even the active document. The below code replaces the code in my original question.
Set Object app as word.
grab the file name.
Make the word doc selected active to manipulate.
Set the word object to the active doc.
THANK YOU EVERYONE!
If FileLocked(strPathFile) Then 'Err.Number = 70 if open
'read / write file in use 'do something
Set wrdApp = GetObject(, "Word.Application")
strPathFile = Right(strPathFile, Len(strPathFile) - InStrRev(strPathFile, "\"))
wrdApp.Documents(strPathFile).Activate ' need to set picked doc as active
Set wrdDoc = wrdApp.ActiveDocument ' works!
This should get you the object you need.
Dim WRDFile As Word.Application
Set WRDFile = GetObject(strPathFile)
'Have Microsoft Word 16.0 Object Library selected in your references
Dim wordapp As Object
Set wordapp = GetObject(, "Word.Application")
wordapp.Documents("documentname").Select
'works if you only have one open word document. In my case, I'm trying to push updates to word links from excel.
I have been tasked with importing the contents of a Microsoft Word Form into my Access database. It's working fine using the following VBA code which is triggered from a form:
Private Sub cmdFileDialog_Click()
On Error GoTo ErrorHandler
Dim objDialog As Object
Dim varFile As Variant
Dim rec, rec2 As Recordset
Dim db As Database
'New Word Document Variables
Dim appWord As Word.Application
Dim doc As Word.Document
Const DEST_TABLE = "ap_behaviour_referrals" 'change to suit
Const PATH_DELIM = "\"
Set objDialog = Application.FileDialog(3)
' Clear listbox contents.
Me.fileList.RowSource = ""
With objDialog
.AllowMultiSelect = False
' Set the title of the dialog box.
.Title = "Please select a behaviour referral to import"
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "Microsoft Word Forms", "*.docx"
.Filters.Add "All Files", "*.*"
.Show
If .SelectedItems.Count = 0 Then
MsgBox "No file selected."
Else
For Each varFile In .SelectedItems
'New docx Variable Actions
Set appWord = GetObject(, "Word.Application")
Set doc = appWord.Documents.Open(varFile)
Next
Set db = CurrentDb
Set rec = db.OpenRecordset(DEST_TABLE)
With rec
.AddNew
' my data
'preformat the date fields from the form
Dim unformattedpupildob As String
Dim formattedpupildob As Date
unformattedpupildob = doc.FormFields("Text2").Result
unformattedpupildob = Replace(unformattedpupildob, ".", "/")
formattedpupildob = Format(unformattedpupildob, "dd/mm/yy")
'And now insert the record into the table
!pupil_name = doc.FormFields("Text1").Result
!pupil_dob = formattedpupildob
!pupil_yr_grp = doc.FormFields("Text3").Result
!pupil_submitted_eth = doc.FormFields("Text4").Result
!pupil_upn = doc.FormFields("Text5").Result
!pupil_looked_after = doc.FormFields("Text6").Result
!sen_pre_statement = doc.FormFields("Text7").Result
!sen_ehcp = doc.FormFields("Text8").Result
!cat_date_final_ehcp = doc.FormFields("Text9").Result
!num_exclusion = doc.FormFields("Text10").Result
!days_exclusion = doc.FormFields("Text11").Result
!sch_name = doc.FormFields("Text12").Result
!sch_no = doc.FormFields("Text14").Result
!contact_name = doc.FormFields("Text13").Result
!contact_role = doc.FormFields("Text40").Result
!contact_email = doc.FormFields("Text31").Result
.Update
.Close
MsgBox "File Processing Complete"
End With
End If
End With
Set objDialog = Nothing
Me.fileList.RowSource = ""
ExitSub:
Set rec = Nothing
Set db = Nothing
'...and set it to nothing
Exit Sub
ErrorHandler:
If Err.Number <> 0 Then
Msg = "Error # " & Str(Err.Number) & " was generated by " & Err.Source & Chr(13) & "Error Line: " & Erl() & Chr(13) & Err.Description
MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
End If
Resume ExitSub
End Sub
All but one of the fields are (badly) bookmarked so I can use this to grab the contents of the field HOWEVER, I've come across an unnamed form field:
Which I need to import and I have no idea how to get the contents of it without a named bookmark.
I have no ability to modify the form since it's controlled by somebody else and is widely distributed, but was wondering if there was any way to pull the contents of this field without it being named?
Thanks!
Like other collections of objects, you can address them either by name (as you do for the other fields) or by numeric index.
For i = 1 To doc.FormFields.Count
Debug.Print i, doc.FormFields(i).Result
Next i
This should give you the index of the field, if you know its content.
Then use !the_answer = doc.FormFields(42).Result in your code. (42 is an example!)
Edit: minimal working example (running in Access):
Public Sub TestWord()
Dim oWord As Word.Application
Dim oDoc As Word.Document
Dim i As Long
Set oWord = CreateObject("Word.Application")
Set oDoc = oWord.Documents.Open("C:\Users\foobar\Documents\Dok1.docx")
oWord.Visible = True
For i = 1 To oDoc.FormFields.Count
Debug.Print i, oDoc.FormFields(i).Name, oDoc.FormFields(i).Result
Next i
oDoc.Close
oWord.Quit
End Sub
The direct window (Ctrl+g) lists all form fields with their index, name = bookmark, and default text.
I have a sub on a form which is intended to allow users to report bugs and suggest improvements to the form. I have it pretty much ready to go, but keep running into issues with adding attachments.
Sub Submit()
Dim OutApp As Object
Dim OutMail As Object
Dim Item
Dim STR As String, AdminOnly As String, TruncBox As String, STRAttachments As String
For Each cCont In Me.MultiPage1.SelectedItem.Controls
Select Case TypeName(cCont)
Case "TextBox"
If cCont.value = "Please enter a short description here." Or _
cCont.value = "Please enter a short description here." Then
MsgBox ("Please enter all information.")
Exit Sub
ElseIf cCont.value = "" Then
MsgBox ("Please enter all information.")
Exit Sub
End If
Case "ComboBox"
If cCont.value = "" Then
MsgBox ("Please enter all information.")
Exit Sub
ElseIf InStr(cCont.value, "Report") Then
TruncBox = "BUG"
Else
TruncBox = "SUGGESTION"
End If
End Select
Next
STR = "{email address redacted}"
If RecipientsListBox.ListCount = 0 Then
AdminOnly = MsgBox("Only admin will receive updates!", _
vbOKCancel + vbExclamation, "No Users on Watch List")
If AdminOnly = vbCancel Then
Exit Sub
Else
STR = STR
End If
Else
For Each Item In RecipientsListBox.List
STR = STR & ";" & Item
Next Item
End If
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
On Error GoTo cleanup
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.to = STR
Call .Recipients.resolveall
.Subject = TruncBox & ": " & ActiveWorkbook.Name & ": " & ShortDescriptionTextBox
.Body = LongDescriptionTextBox
If AttachmentsListBox.ListCount = 0 Then
Else
For Each Item In AttachmentsListBox.List
STRAttachments = Item
.Attachments.Add STRAttachments
Next Item
End If
'.Send 'Or use Display
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
I have run through various attempts at looping through each item on the AttachmentsListBox control, and ready to ask for help. This latest attempt produced Run-time error '94': Invalid use of Null with the line STRAttachments = Item returning null in the highlighted section. Looking at what I already have, and comparing to other searches on the internet, I don't understand. I returned variant Item to STR in the line STR = STR & ";" & Item above, and I've seen other examples of strings being returned as attachments. What am I missing?
So, this is a problem that I have identified in the past, but I haven't thoroughly researched the root cause. ListBox.List returns a multi-dimensional array of ListObjects. So, even though you have a ListBox with 1 column, the List array has multiple columns. When you loop over with a For Each loop, it tries to access values in these other columns, which just result in a Null value. Try using a For loop with a counter, such as:
Private Sub UserFormButton_Click()
For i = 0 To Me.ListBox1.ListCount - 1
MsgBox Me.ListBox1.List(i)
Next i
End Sub
Im seeking for help as i have a bulk of links to check if the link is broken i have tried the below macro but it works twice and after that it is no longer working i am using ms office 10 64bit i would like to add on the macro if macro
can check the image resolution for example if i paste url on column A it will highlight the broken links and on column b it will show the image resolution
Sub Audit_WorkSheet_For_Broken_Links()
If MsgBox("Is the Active Sheet a Sheet with Hyperlinks You Would Like to Check?", vbOKCancel) = vbCancel Then
Exit Sub
End If
On Error Resume Next
For Each alink In Cells.Hyperlinks
strURL = alink.Address
If Left(strURL, 4) <> "http" Then
strURL = ThisWorkbook.BuiltinDocumentProperties("Hyperlink Base") & strURL
End If
Application.StatusBar = "Testing Link: " & strURL
Set objhttp = CreateObject("MSXML2.XMLHTTP")
objhttp.Open "HEAD", strURL, False
objhttp.Send
If objhttp.statustext <> "OK" Then
alink.Parent.Interior.Color = 255
End If
Next alink
Application.StatusBar = False
On Error GoTo 0
MsgBox ("Checking Complete!" & vbCrLf & vbCrLf & "Cells With Broken or Suspect Links are Highlighted in RED.")
End Sub
Edit: I changed your macro to declare variables properly and release objects upon macro completion; this should address any potential memory issues. Please try this code and let me know if it works.
Sub Audit_WorkSheet_For_Broken_Links()
If MsgBox("Is the Active Sheet a Sheet with Hyperlinks You Would Like to Check?", vbOKCancel) = vbCancel Then
Exit Sub
End If
Dim alink As Hyperlink
Dim strURL As String
Dim objhttp As Object
On Error Resume Next
For Each alink In Cells.Hyperlinks
strURL = alink.Address
If Left(strURL, 4) <> "http" Then
strURL = ThisWorkbook.BuiltinDocumentProperties("Hyperlink Base") & strURL
End If
Application.StatusBar = "Testing Link: " & strURL
Set objhttp = CreateObject("MSXML2.XMLHTTP")
objhttp.Open "HEAD", strURL, False
objhttp.Send
If objhttp.statustext <> "OK" Then
alink.Parent.Interior.Color = 255
End If
Next alink
Application.StatusBar = False
'Release objects to prevent memory issues
Set alink = Nothing
Set objhttp = Nothing
On Error GoTo 0
MsgBox ("Checking Complete!" & vbCrLf & vbCrLf & "Cells With Broken or Suspect Links are Highlighted in RED.")
End Sub
Old Answer Below
Combining your macro (which seems to be from here) with an alternative found on excelforum yields the below code. Give it a try and let me know if it works for you.
Sub TestHLinkValidity()
Dim rRng As Range
Dim fsoFSO As Object
Dim strPath As String
Dim cCell As Range
If MsgBox("Is the Active Sheet a Sheet with Hyperlinks You Would Like to Check?", vbOKCancel) = vbCancel Then
Exit Sub
End If
Set fsoFSO = CreateObject("Scripting.FileSystemObject")
Set rRng = ActiveSheet.UsedRange.Cells
For Each cCell In rRng.Cells
If cCell.Hyperlinks.Count > 0 Then
strPath = GetHlinkAddr(cCell)
If fsoFSO.FileExists(strPath) = False Then cCell.Interior.Color = 65535
End If
Next cCell
End Sub
Function GetHlinkAddr(rngHlinkCell As Range)
GetHlinkAddr = rngHlinkCell.Hyperlinks(1).Address
End Function
Is it possible with VBA Excel to download data from a website without affecting other tasks? What I want to achieve is to be able to press a button and keep working on other tasks. Right now, when I run the code below, I can't perform other tasks or the code will break. Thanks for everyone's help/input!
Public Sub Get_File()
Dim sFiletype As String 'Fund type reference
Dim sFilename As String 'File name (fund type + date of download), if "" then default
Dim sFolder As String 'Folder name (fund type), if "" then default
Dim bReplace As Boolean 'To replace the existing file or not
Dim sURL As String 'The URL to the location to extract information
Dim pURL As String
Dim Cell, Rng As Range
Dim Sheet As Worksheet
Dim oBrowser As InternetExplorer
Set oBrowser = New InternetExplorer
Dim StartTime As Double
Dim SecondsElapsed As Double
StartTime = Timer
'Initialize variables
Set Rng = Range("I2:I15")
Set Sheet = ActiveWorkbook.Sheets("Macro_Button")
For Each Cell In Rng
If Cell <> "" Then
sFiletype = Cell.Value
sFilename = sFiletype & "_" & Format(Date, "mmddyyyy")
sFolder = Application.WorksheetFunction.VLookup(Cell.Value, Sheet.Range("I2:Z15"), 2, False)
bReplace = True
sURL = "www.preqin.com"
pURL = Application.WorksheetFunction.VLookup(Cell.Value, Sheet.Range("I2:Z15"), 16, False)
'Download using the desired approach, XMLHTTP / IE
If Application.WorksheetFunction.VLookup(Cell.Value, Sheet.Range("I2:Z15"), 15, False) = 1 Then
Call Download_Use_IE(oBrowser, sURL, pURL, sFilename, sFolder, bReplace)
Else
Call Download_NoLogin_Use_IE(oBrowser, pURL, sFilename, sFolder, bReplace)
End If
Else: GoTo Exit_Sub
End If
Next
Exit_Sub:
'Close IE
oBrowser.Quit
'Determine how many seconds code took to run
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
Private Sub Download_Use_IE(oBrowser As InternetExplorer, _
ByRef sURL As String, _
ByRef pURL As String, _
Optional ByRef sFilename As String = "", _
Optional ByRef sFolder As String = "", _
Optional ByRef bReplace As Boolean = True)
Dim hDoc As HTMLDocument
Dim objInputs As Object
Dim ele As Object
On Error GoTo ErrorHandler
oBrowser.Visible = True
'Navigate to URL
Call oBrowser.navigate(sURL)
While oBrowser.Busy Or oBrowser.readyState <> 4: DoEvents: Wend
'Skips log in step if already signed into website
On Error GoTo LoggedIn
'Enter username
oBrowser.document.getElementById("ctl00_ctl00_cphSiteHeader_ucLoginForm_user_email").Value = "XXX"
oBrowser.document.getElementById("ctl00_ctl00_cphSiteHeader_ucLoginForm_user_password").Value = "XXX"
'Submit the sign in
oBrowser.document.getElementById("ctl00_ctl00_cphSiteHeader_ucLoginForm_btnLogin").Click
'Wait for website to load
While oBrowser.Busy Or oBrowser.readyState <> 4: DoEvents: Wend
LoggedIn:
'Initial data export
oBrowser.navigate (pURL)
'Wait for website to load
While oBrowser.Busy Or oBrowser.readyState <> 4: DoEvents: Wend
'Set the htmldocument
Set hDoc = oBrowser.document
'Loop and click the download file button
Set objInputs = oBrowser.document.getElementsbyTagName("input")
For Each ele In objInputs
If ele.Title Like "Download Data to Excel" Then
ele.Click
End If
Next
'Wait for dialogue box to load
While oBrowser.Busy Or oBrowser.readyState > 3: DoEvents: Wend
Application.Wait (Now + TimeValue("0:00:02"))
'IE 9+ requires to confirm save
Call Download(oBrowser, sFilename, sFolder, bReplace)
Exit Sub
ErrorHandler:
'Resume
Debug.Print "Sub Download_Use_IE() " & Err & ": " & Error(Err)
End Sub
Try the
DoEvents
As far i know, is not easy to work with background process and excel.
Cheers.
You cannot work on the Workbook that is running the macro. You can open another instance of Excel, or a read only copy of the workbook running the macro if you would like to work within Excel while the macro is running. This question has been asked and answered before on here
It is difficult to determine from your question whether you are talking about "other tasks" as in within Excel or just on your computer in general. My above paragraph answers whether you can do tasks within Excel while the macro is running.