wdReplaceAll is Empty - vba

Currently I am using a for loop to lay down 4 rounds of data, I was hoping to have it replace all that are corresponding to the current word template, but doing this all in excel VBA
Unfortunately the code that I am not using is no working and the wdReplaceAll = Empty.
I've tried resetting parameters and even having .Execute Replace:=wdReplaceAll changed to .Execute Replace:=1. But Nothing in my word document is being replaced
Dim WordApp As Object
Dim DocFileName As String
Set WordApp = CreateObject("Word.Application")
DocFileName = ActiveWorkbook.Path & "\Word\TCAP Update.docx"
WordApp.Documents.Open DocFileName
For i = 1 To TCAPCount
Summary(i) = ActiveCell.Offset(0, -1).Value
Key(i) = ActiveCell.Offset(0, -2).Value
Updated(i) = Format(ActiveCell.Offset(0, 1).Value, "MM/DD/YYYY")
Cells.Find(what:="NEAR DATE", After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=True).Activate
ColorInd = ActiveCell.DisplayFormat.Interior.Color
ActiveCell.Offset(0, 1).Select
Do Until ActiveCell.Value <> "NEAR DATE" And ActiveCell.DisplayFormat.Interior.Color = ColorInd
ActiveCell.Offset(0, 1).Select
Loop
ActualDate(i) = Format(ActiveCell.Value, "MM/DD/YYYY")
ActualDateNam(i) = Range(Split(ActiveCell(1).Address(1, 0), "$")(0) & "1").Value
Range(SEMCol & ActiveCell.Row).Select
Do
ActiveCell.Offset(1, 0).Select
If ActiveCell.EntireRow.Hidden = True Then
'keep looking
Else
Exit Do
End If
Loop
Next i
If TCAPCount > 1 Then
MsgBox "Please take this time to create " & TCAPCount & " extra TCAP Templates for " & SEM
WordApp.Visible = True
MsgBox "When you are ready to proceed please select OK"
End If
For i = 1 To TCAPCount
With WordApp.Selection.Find
.Text = "Key " & (i)
.Replacement.Text = Key(i)
.Execute Replace:=wdReplaceAll
.Text = "Summary " & (i)
.Replacement.Text = Summary(i)
.Execute Replace:=wdReplaceAll
.Text = "ActualDate " & (i)
.Replacement.Text = ActualDate(i)
.Execute Replace:=wdReplaceAll
.Text = "ActualDateNam " & (i)
.Replacement.Text = ActualDateNam(i)
.Execute Replace:=wdReplaceAll
.Text = "Updated " & (i)
.Replacement.Text = Updated(i)
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next i
I am hoping to replace
Key 1 | Summary 1
ActualDateNam 1– ActualDate 1
Last Update: Updated 1
Key 2 | Summary 2
ActualDateNam 2– ActualDate 2
Last Update: Updated 2
Key 3 | Summary 3
ActualDateNam 3– ActualDate 3
Last Update: Updated 3
Key 4 | Summary 4
ActualDateNam 4– ActualDate 4
Last Update: Updated 4
with it's corresponding data ie i=1 and Key (i) = "Apples", then Key 1 will be replaced as "Apples".

If you use Option Explicit, vba compiler would complain about not knowingwdReplaceAllas you use late-bound word object, what prevents you using its enums.
You tried to fix that, but who told you thatwdReplaceAll = 1?
If you read the docs you see wdReplaceAll = 2

Related

Keep Receiving a 424 Debug Error w/ File Name

Please see the bold code below. The debugger says that it is what's causing the 424 "Object Required" error. Any insight/help on this would be greatly appreciated.
Sub GraywolfPlanful()
Dim sForecastFile, sUploadFile, sTab As String
Dim i As Integer
Application.ScreenUpdating = False
sForecastFile = GraywolfWorkbook.Name
Workbooks.Add
sUploadFile = GraywolfWorkbook.Name
Range("A1") = "Company"
Range("B1") = "Department"
Range("C1") = "Location"
Range("D1") = "Segment"
Range("E1") = "Account"
Range("F1") = "Year"
Range("G1") = "Month"
Range("H1") = "Amount"
Range("A2").Select
Windows(sForecastFile).Activate
sTab = Format(Sheets("00_No Department").Range("C1"), "yyyy-mm mmm") & "Project Forecast"
For i = 4 To Sheets.Count
Sheets(i).Select
Range("F6").Select
Do Until (Range("C") = "End" And Range("D") = "Subtotal Other G&A")
If Range("Z" & ActiveCell.Row) <> "" Then
Range("Z" & ActiveCell.Row, "AD" & ActiveCell.Row).Copy
Windows(sUploadFile).Activate
Range(ActiveCell, ActiveCell.Offset(12, 0)).PasteSpecial xlPasteValues
Range("B" & ActiveCell.Row, "B" & ActiveCell.Row + 12) = "Test"
Windows(sCurrentFile).Activate
End If
Loop
Next i
Windows(sUploadFile).Activate
GraywolfWorkbook.SaveAs CurDir & "\Test File Graywolf"
Application.ScreenUpdating = True
End Sub

Merging 2 cells where cell numbers are variable

I have to merge 2 cells where the range might vary at every run. I am trying with the below code, but there is some error with the code, which I am not able to identify. For fixed range its working fine, but for variable it is showing error. Line no is the cell number which needs to be merged, and it will vary at every run:
Range("D" & line_no & ":" "E" & line_no & ).Select
Range("D" & line_no).Activate
With Selection
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
I would try to get rid of the Select in general. You could do it like this:
With Range("D" & line_no & ":" & "E" & line_no)
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
Your problem lies in string concatenation. Comments cover that part.
If this range would be used throughout the program, I'd recommend stroing this range in variable:
define string which will point desired range: Dim rng As String: rng = "D" & line_no & ":E" & line_no, then use it like this:
Range(rng).Select
Range(rng).Activate
OR
define range and store range in the variable instead of a string"
Dim rng As Range
Set rng = Range("D" & line_no & ":E" & line_no)
rng.Select
rng.Activate
'...

Autofill method of range class failed - help needed for my code

I've been trying to make this work. It worked fine on my x64 version of office but not the x86 on my colleagues' computers. Can anyone gimme a fix please?
The VBA engine highlighted Range("AV5").AutoFill Destination:=Range("AV5:AV" & NoOfClients) as the cause
Private Sub Check_Cases_Click()
Dim NoOfClients As Long
Application.DisplayAlerts = False
CO_Select = Application.InputBox("Please input the name of caseworker you would like to check on.", "Caseworker Name")
Range("A2").value = CO_Select
Application.ScreenUpdating = False
NoOfClients = Range("C2").value
CO_Name = Range("A2").value
CheckCaseMsg = MsgBox(CO_Name & ", there are " & NoOfClients & " clients under your name." & vbNewLine & vbNewLine & _
"System will now calculate all your active cases and display " & vbNewLine & _
"all the clients for your information." & vbNewLine & vbNewLine & _
"Confirm?", vbYesNo, "Case Checking")
If CheckCaseMsg = vbNo Then
Exit Sub
End If
If CheckCaseMsg = vbYes Then
'Remove the filters if one exists
'=========================================
If ActiveSheet.FilterMode Then
Selection.AutoFilter
End If
Clear
Startup_Formula
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Range("AV5").AutoFill Destination:=Range("AV5:AV" & NoOfClients)
Application.Calculation = xlCalculationAutomatic
Range("GI_Table[[#All],[Client number]]").Copy
Range("GI_Table[[#All],[Client number]]").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Application.ScreenUpdating = True
ActiveSheet.ListObjects("GI_Table").Range.AutoFilter Field:=2, Criteria1:= _
Array("ACTIVE", "INACTIVE", "RENEWED"), Operator:=xlFilterValues
GI_CustomSort
GI_CustomSort
MsgBox "Case Checking Ready", vbInformation, "Ready"
End If
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Instead of just Range(".."). you should try
Dim sht as Worksheet
Set sht = Worksheets("Name")
sht.Range("..")
and so on.
You will get the Autofill method of range class failed error if the value of NoOfClients is 5. The end row is the same as the start row. Here is a simple way to reproduce the error.
Sub Sample()
NoOfClients = 5
Range("AV5").AutoFill Destination:=Range("AV5:AV" & NoOfClients)
End Sub
An alternative to .Autofill is to directly write to the range. For ex:
Range("AV5:AV" & NoOfClients).Formula = Range("AV5").Formula
Ok I know what's the problem now, I think.
I limited my scroll area in the Sub for Worksheet_Activate and the value of NoOfClients exceeded the allowed amount!
So I deleted that and I think it's ok now! This is my final code (with the scroll area becoming dynamic now)
Private Sub Check_Cases_Click()
Dim NoOfClients As Long
ActiveSheet.ScrollArea = ""
Application.Calculation = xlCalculationAutomatic
Application.DisplayAlerts = False
CO_Select = Application.InputBox("Please input the name of caseworker you would like to check on.", "Caseworker Name")
Range("A2").value = CO_Select
Application.ScreenUpdating = False
NoOfClients = Range("C2").value
CO_Name = Range("A2").value
CheckCaseMsg = MsgBox(CO_Name & ", there are " & NoOfClients & " clients under your name." & vbNewLine & vbNewLine & _
"System will now calculate all your active cases and display " & vbNewLine & _
"all the clients for your information." & vbNewLine & vbNewLine & _
"Confirm?", vbYesNo, "Case Checking")
If CheckCaseMsg = vbNo Then
Exit Sub
End If
If CheckCaseMsg = vbYes Then
'Remove the filters if one exists
'=========================================
If ActiveSheet.FilterMode Then
Selection.AutoFilter
End If
Clear
Startup_Formula
'Fill down the formula for n times where n= No of Clients of the Caseworker'
'=============================================================================
Dim Sht As Worksheet
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Set Sht = Worksheets("Grand Info Sheet")
NoOfClients = Range("C2").value
NoOfClientsAdjusted = NoOfClients + 4
Sht.Range("AV5").AutoFill Destination:=Sht.Range("AV5:AV" & NoOfClientsAdjusted)
Application.Calculation = xlCalculationAutomatic
Range("GI_Table[[#All],[Client number]]").Copy
Range("GI_Table[[#All],[Client number]]").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Application.ScreenUpdating = True
GI_CustomSort
MsgBox "Case Checking Ready", vbInformation, "Ready"
Range("A1").Select
End If
ActiveSheet.ScrollArea = "A1:AW" & NoOfClientsAdjusted + 5
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

Get stock/company names from Yahoo Finance using VBA

The whole code is trying to get historical data from Yahoo Finance using VBA. Everything works pretty fine except the code whereby I try to get the company's name using from the Yahoo site.
This first piece of code is just to chceck that there are no mistakes in the definition in variables or whatever.
Enum READYSTATE
READYSTATE_UNINITIALIZED = 0
READYSTATE_LOADING = 1
READYSTATE_LOADED = 2
READYSTATE_INTERACTIVE = 3
READYSTATE_COMPLETE = 4
End Enum
Sub GetData()
Dim datasheet As Worksheet
Dim EndDate As Date
Dim StartDate As Date
Dim symbol As String
Dim qurl As String
Dim nQuery As Name
Dim LastRow As Integer
Dim ohtml As HTMLText
On Error GoTo error_getdata
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual
Set datasheet = ActiveSheet
StartDate = datasheet.Range("startDate").Value
EndDate = datasheet.Range("endDate").Value
symbol = datasheet.Range("ticker").Value
symbol = UCase(symbol)
'Download data from Yahoo Finance'
Sheets("Home").Activate
Sheets(symbol).Range("a1").CurrentRegion.ClearContents
qurl = "http://ichart.finance.yahoo.com/table.csv?s=" & symbol
qurl = qurl & "&a=" & Month(StartDate) - 1 & "&b=" & Day(StartDate) & _
"&c=" & Year(StartDate) & "&d=" & Month(EndDate) - 1 & "&e=" & _
Day(EndDate) & "&f=" & Year(EndDate) & "&g=" & Sheets(symbol).Range("a1") & "&q=q&y=0&z=" & _
symbol & "&x=.csv"
eurl = "https://finance.yahoo.com/quote/" & symbol & "?ltr=2"
Here is where the problem spots. I try to scrap the html of the site looking for the company's name. If I look at the html code of the website, I find that the company's name is labeled as reactid="239". I guess that what I have to do is to use getelementsbyID("239") but I am not sure about that.
'''''
Dim objIe As Object
Set objIe = CreateObject("InternetExplorer.Application")
objIe.Visible = False
objIe.navigate eurl
Application.StatusBar = "Looking for information in Yahoo Finance"
While (objIe.Busy Or objIe.READYSTATE <> 4): DoEvents: Wend
Set xobj = objIe.querySelectorAll("[reactid=239]")
Debug.Print xobj.innerText
Set xobj = Nothing
objIe.Quit
Set objIe = Nothing
Application.StatusBar = ""
'Sort the existence of a ticker in our sheet and create a new one '
Dim worksh As Integer
Dim worksheetexists As Boolean
Dim x As Integer
worksh = Application.Sheets.Count
worksheetexists = False
For x = 1 To worksh
If Worksheets(x).Name = symbol Then
worksheetexists = True
Sheets(symbol).Delete
ActiveWorkbook.Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = symbol
Exit For
End If
Next x
If worksheetexists = False Then
ActiveWorkbook.Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = symbol
End If
' Load data '
QueryQuote:
With Sheets(symbol).QueryTables.Add(Connection:="URL;" & qurl, Destination:=Sheets(symbol).Range("a1"))
.BackgroundQuery = True
.TablesOnlyFromHTML = False
.Refresh BackgroundQuery:=False
.SaveData = True
End With
Sheets(symbol).Range("a1").CurrentRegion.TextToColumns Destination:=Sheets(symbol).Range("a1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=True, Space:=False, other:=False
Sheets(symbol).Columns("A:G").ColumnWidth = 12
'Sort data'
LastRow = Sheets(symbol).UsedRange.Row - 2 + Sheets(symbol).UsedRange.Rows.Count
Sheets(symbol).Sort.SortFields.Add Key:=Range("A2"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With Sheets(symbol).Sort
.SetRange Range("A1:G" & LastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
.SortFields.Clear
End With
Exit Sub
error_getdata:
MsgBox ("Fatal error. Please insert a valid sticker for the stock")
End Sub
I heed that this could not be the most efficient way to get what I want. First I want to learn how to get it done and then I will take on the efficiency of the program.
Edit: Using some answers, I edited a bit the code, it still shows up an error (error 438) on the line:
Set xobj = objIe.querySelectorAll("[reactid=239]")
I'd look into using http://www.w3schools.com/jsref/met_document_queryselectorall.asp
which can allow selection of nodes using CSS selector syntax and there is a reference for this syntax at http://www.w3schools.com/cssref/css_selectors.asp
So perhaps something along the lines of
document.querySelectorAll("[reactid=239]")
Incidentally, you can browse the library if you use a Tools Reference to
Microsoft HTML Object Library

Loop code to run macro multiple times

I have this vba macro that extracts data from a text file and puts it into a column in Excel. The files are named by days (2016mmdd). Currently, I run this macro for each day. Now I want it such that when this Macro is run, the data for all the days in the declared month (say August) will be automatically extracted into different columns (a column per each day of the month). So that I won't have to manually run it 31 times if there are 31 days in the month. Thanks for helping.
Sub Macro7()
'
' Macro7 Macro
'
' Keyboard Shortcut: Ctrl+x
'
Dim fileDate, rng, rng1, rng2, rng3, rcell As String
b = InputBox("Enter file Name mmdd", "File name")
rcell = InputBox("Enter cell reference", "Reference name")
rng = "$" & rcell & "$2"
rng1 = rcell & "2:" & rcell & "14"
rng2 = rcell & "52:" & rcell & "62"
rng3 = rcell & "2:" & rcell & "101"
Filename = "j:\files\2016" & b & "2259.txt"
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;j:\files2016" & b & "2259.txt", Destination:= _
Range(rng))
.Name = "tr" & b
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 850
.TextFileStartRow = 1
.TextFileParseType = xlFixedWidth
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(9, 1, 9)
.TextFileFixedColumnWidths = Array(103, 4)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
Range(rng1).Select
Selection.Delete Shift:=xlUp
ActiveWindow.SmallScroll Down:=45
Range(rng2).Select
Selection.Delete Shift:=xlUp
ActiveWindow.SmallScroll Down:=-60
Range(rng3).Select
End Sub
The quick approach would be to re-write Sub Macro7() to accept parameters, e.g.
Sub ImportFiles(FName As String, ColNum As Integer)
' blablabla
' work with range objects ... not with patched strings containing range addresses
Dim Rng As Range, Rng1 As Range, Rng2 As Range, Rng3 As Range
Set Rng = Cells(2, ColNum)
Set Rng1 = Range(Cells(2, ColNum), Cells(14, ColNum))
Set Rng2 = Range(Cells(52, ColNum), Cells(62, ColNum))
Set Rng3 = Range(Cells(2, ColNum), Cells(101, ColNum))
Filename = "j:\files\2016" & FName & "2259.txt"
' and replace <Destination := Range(Rng)> by <Destination := Rng>
' blablabla
' use the range objects defined/set earlier ... save on Select/Selection
Rng1.Delete xlUp
Rng2.Delete xlUp
Rng3.Select
End Sub
and have a calling Macro e.g.
Sub DoWorklist()
ImportFiles "0901", 1
ImportFiles "0902", 2
ImportFiles "0903", 3
' blablabla
'alternative
Dim Idx As Integer
For Idx = 1 To 30
' to overcome well spotted chr() issue we convert running number Idx
' into 2 digit string with leading "0"
ImportFiles "09" & Format(Idx, "00"), Idx
Next Idx
End Sub