Changing a VBA script using a VBScript or CMD - vba

I have looked everywhere and I didn't find any solution for my problem.
What I need is to change a part of my VBA using a VBscript (or even a CMD).
I have something like this:
Sub Test
If ActiveSheet.AutoFilterMode = True Then ActiveSheet.AutoFilterMode = False
NameColumn = Application.WorksheetFunction.Match("Names", Range(Cells(line, column), Cells(line, column + 30)), 0)
Cells(line, colum).Select
Selection.AutoFilter Field:=NameColumn, Criteria1:="=*ABC*", _
Operator:=xlAnd
Selection.End(xlDown).Select
If ActiveCell.Row < 1000 Then
Call Copy("ABC")
End If
SendEmail("ABC is done", emailaddress)
End Sub
What I wanted is a script to change ABC to CDE, FGH and IJK, for instance.
I have a script in VBS which change part of my code if I want:
Const ToRead= 1
Const ToWrite= 2
File= Wscript.Arguments(0)
OldText= Wscript.Arguments(1)
NewText = Wscript.Arguments(2)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(File, ToRead)
strText = objFile.ReadAll
objFile.Close
NewText = Replace(strText, OldText, NewText)
Set objFile = objFSO.OpenTextFile(File, ToWrite)
objFile.Write NewText
objFile.Close
And I also have a code to run a VBA using a VBS:
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("C:\Documents\Example.xlsm")
xlApp.Run "RunMacro"
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
However, I really cant see a connection between those scripts and I didnt find anything on the internet about this problem.
Does anyone know how can I change a part of the VBA code using the VBS?
Using VBS would be the best way to do that, because of other parts of the process I am running. But I would accept different answers.

What about using parametr for your Test sub and pass it using xlApp.Run:
xlApp.Run "Example.xlsm!Test", "ABC"
Test sub with parametr:
Sub Test(str As String)
If ActiveSheet.AutoFilterMode = True Then ActiveSheet.AutoFilterMode = False
NameColumn = Application.WorksheetFunction.Match("Names", Range(Cells(Line, Column), Cells(Line, Column + 30)), 0)
Cells(Line, colum).Select
Selection.AutoFilter Field:=NameColumn, Criteria1:="=*" & str & "*", _
Operator:=xlAnd
Selection.End(xlDown).Select
If ActiveCell.Row < 1000 Then
Call Copy(str)
End If
Call SendEmail(str & " is done", emailaddress)
End Sub

Related

Autofilter loop using array

I am having trouble debugging my code. I have an array with the criterial of an autofilter column. My code is supposed to loop through the array, open a set of files and copy-paste information into my workbook.
When I run the code it does not autofiler to the desired criterial and shows a Run-time error 1004. I already tried searching for solutions or similar problems, but found nothing. I also tried recording a macro to change the approach, but when trying to implement the loop it does not work :(
Any help is appreaciated!
Sub Update_Database()
Dim directory As String
Dim fileName As String
Dim my_array() As String
Dim iLoop As Integer
ReDim my_array(18)
my_array(0) = "Aneng"
my_array(1) = "Bayswater"
my_array(2) = "Bad Blankenburg"
my_array(3) = "Halstead"
my_array(4) = "Jorf Lasfar"
my_array(5) = "Kolkatta"
my_array(6) = "Marysville"
my_array(7) = "Northeim"
my_array(8) = "Ponta Grossa"
my_array(9) = "Puchov"
my_array(10) = "Renca"
my_array(11) = "Padre Hurtado"
my_array(12) = "Shanxi"
my_array(13) = "San Luis Potosi"
my_array(14) = "Szeged"
my_array(15) = "Tampere"
my_array(16) = "Uitenhage"
my_array(17) = "Veliki Crljeni"
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Show
directory = .SelectedItems(1)
Err.Clear
End With
fileName = Dir(directory & "\", vbReadOnly)
Dim mwb As Workbook
Set mwb = Workbooks("OEE_Database_Final.xlsm")
Do While fileName <> ""
For iLoop = LBound(my_array) To UBound(my_array)
On erro GoTo ProcExit
With Workbooks.Open(fileName:=directory & "\" & fileName, UpdateLinks:=False, ReadOnly:=True)
Selection.AutoFilter Field:=1, Criterial:=my_array(iLoop)
mwb.Worksheets(8).Range("O9:Z2945") = .Worksheets(8).Range("O9:Z2945").Value2
.Close SaveChanges:=False
End With
fileName = Dir
Next iLoop
Loop
ActiveSheet.ShowAllData
ProcExit:
Exit Sub
End Sub

PasteSpecial Method Odd Error

I have gone through the similar questions and have not found anything with this specific error.
I am trying to make a macro that goes through a large number of CSV files, pulls the necessary information I need, copies and pastes that data to a new Workbook, and then closes the CSV file and goes to the next one.
When I test my code and have it run Step by Step (using F8) it functions fine and there are no error. However, whenever I try and just have the code run (like pressing F5) I get the error "PasteSpecial Method of Class Range" failed. When I press debug this line of the code is highlighted:
copyRange.Offset(0, 1).PasteSpecial Paste:=xlPasteValues
I added a small time delay of 0.5s before this line and it actually was able to go further through the files before failing.
Is it something with the Range.Offset method? Should I explicitly define a different copy range?
Code I have follows below:
Public Sub OpenTXT_CopyNewWBK(inPath As String)
Application.ScreenUpdating = False
Dim fso, oFolder, oSubfolder, oFile, queue As Collection
Dim app As New Excel.Application
app.Visible = True
Dim dataRange As Range, dateRange As Range, copyRange As Range
Dim lastCell, lastRow As String
Dim newBook, wbk As Excel.Workbook
Dim csvStart As Long
Set newBook = Workbooks.Add
With newBook
.SaveAs Filename:="BETA RAY " & Format(Now, "ddmmyyhhmmss")
End With
Set fso = CreateObject("Scripting.FileSystemObject")
Set queue = New Collection
queue.Add fso.GetFolder(inPath) 'obviously replace
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Do While queue.Count > 0
Set oFolder = queue(1)
queue.Remove 1 'dequeue
For Each oSubfolder In oFolder.SubFolders
queue.Add oSubfolder 'enqueue
Next oSubfolder
For Each oFile In oFolder.Files
Set wbk = app.Workbooks.Add(oFile.Path)
lastCell = wbk.Sheets(1).Range("A1").End(xlDown).Address
If Len(lastCell) = 6 Then
lastRow = Mid(lastCell, 4, 3)
ElseIf Len(lastCell) = 5 Then
lastRow = Mid(lastCell, 4, 2)
ElseIf Len(lastCell) = 4 Then
lastRow = Mid(lastCell, 4, 1)
End If
Set dateRange = wbk.Sheets(1).Range("A2", lastCell)
dateRange.Select
Set dataRange = wbk.Sheets(1).Range("AA2", "AM" & lastRow)
dataRange.Select
wbk.Application.CutCopyMode = True
Set copyRange = Workbooks(newBook.name).Sheets(1).Range("A1048576").End(xlUp)
If Not copyRange = "" Then
Set copyRange = copyRange.Offset(1, 0)
End If
dateRange.Copy
copyRange.PasteSpecial Paste:=xlPasteValues
wbk.Application.CutCopyMode = False
wbk.Application.CutCopyMode = True
Application.Wait (Now + 500 * 0.00000001)
dataRange.Copy
copyRange.Offset(0, 1).PasteSpecial Paste:=xlPasteValues
wbk.Application.CutCopyMode = False
wbk.Close SaveChanges:=False
Next oFile
Loop
app.Quit
Set app = Nothing
Range("B:B").Delete
Range("G:G").Delete
Range("L:L").Delete
Application.ScreenUpdating = True
End Sub
I am sure there are much better ways to do a lot of the things I have going on there. I really just use VBA to make my life easier at work so a lot of the code I use is copy, pasted, and modified to fit my needs. I couldn't figure out how to make this method work wbk2.sht2.Range("A1:A5") = wbk1.sht1.Range("B1:B5") everything I have read says this should be a much better method. Also, the portions of code that read dataRange.Select and dateRange.Select are just there for debugging purposes.
try this....
wbk2.sht2.Range("A1:A5").value = wbk1.sht1.Range("B1:B5").value

VBA - Checking Two Different Path Locations

I have an existing VBA Project that I simply need to modify even if does scream to be re-written one day.
The sheet has a hidden sheet called Options that lists a file path in B3 and that path is called \fileserver\Drafting\MBS_JOBS\
The code then assigns a variable this path:
strpathtofile = Sheets("Options").Range("B3").Value
Finally, later on, it puts it all together with this:
strFileToOpen = strpathtofile & ActiveCell.Value & strFilename
What I need to do now is have it check a second path. So I've duplicated some of the code.
I first put the new path in B7 of the OPTIONS page. Then, I created a variable and assigned it:
Public strpathtoProj As String
strpathtoProj = Sheets("Options").Range("B7").Value
So, what I need to do is have this program also check this other path. So wondering if I need some kind of IF, THEN or ELSE statement around this part:
strFileToOpen = strpathtofile & ActiveCell.Value & strFilename
To also make it look at strpathtoProj.
I'm a "work in progress" VBA developer as a SOLO IT guy for a small business and am learning as I go.
Here are the modules that use strpathtofile (and you can see that I've already got some code in there for the strpathtoProj that I now need to use):
Sub RUN_SUMMARY_REPORT()
'assign variable... this is here just in case they haven't ran the "TEST" button
strpathtofile = Sheets("Options").Range("B3").Value
strFilename = Sheets("Options").Range("B4").Value
strThisBook = Sheets("Options").Range("B5").Value
strExtraInformation = Sheets("Options").Range("B6").Value
strpathtoProj = Sheets("Options").Range("B7").Value
'assign variable... this is here just in case they haven't ran the "TEST" button
Application.ScreenUpdating = False
Application.DisplayAlerts = False
ActiveSheet.Unprotect
'Remove any past data
SHOW_WARNING (False)
' Extended The Range To Remove data that continued below line 44. Brian
1/20/2015
' Range("C2:C200").ClearContents ' Jobs
Range("F4:S13").ClearContents ' Bar
Range("G17:G23").ClearContents ' Web Plate
Range("J17:J19").ClearContents ' Cable
Range("M17:M23").ClearContents ' Rod
Range("P17:P25").ClearContents ' Angle
'Remove any past data
'initialize ExtraInformation
Sheets(strExtraInformation).Range("A1:K1000").ClearContents
Sheets(strExtraInformation).Select
Range("A1").Select
'initialize ExtraInformation
SHOW_SHEETS (True)
INITIALIZE_PUBLIC_VARS
IMPORT_ALL_INFORMATION
PRINT_WEB_DATA
PRINT_BAR_DATA
PRINT_BRAC_DATA
PRINT_ROD_DATA
PRINT_ANGLE_DATA
SHOW_SHEETS (False)
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
End Sub
Sub TEST_FOR_BAD_JOB_MUMBERS()
Dim bFound As Boolean
On Error GoTo EXPLAIN
Application.ScreenUpdating = False 'increase performance
Application.DisplayAlerts = False
'Unhide all sheets
Sheets("REPORT").Visible = True
'Unhide all sheets
'Get all of the settings for this macro and assign variables
strpathtofile = Sheets("Options").Range("B3").Value
strFilename = Sheets("Options").Range("B4").Value
strpathtoProj = Sheets("Options").Range("B7").Value
'Get all of the settings for this macro and assign variables
Sheets("REPORT").Select
ActiveSheet.Unprotect
Range("C2").Select
Do Until ActiveCell.Value = ""
bFound = True
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject") 'Wow! What an
efficiency increase!
If Not fso.FileExists(strpathtofile & ActiveCell & strFilename) Then 'Wow!
What an efficiency increase!
Error (53) 'file not found error
End If
ActiveCell.Font.Color = RGB(0, 0, 0)
ActiveCell.Font.Bold = False
ActiveCell.Offset(1, 0).Select
Loop
Range("c2").Select
'Clean up the look of this thing!
Sheets("Options").Visible = False
Sheets("REPORT").Select
If bFound Then
MsgBox "Test Has Passed! All Job Numbers Found on X-Drive"
Else
MsgBox "No Jobs!"
End If
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
Exit Sub
EXPLAIN:
'Clean up the look of this thing!
Sheets("Options").Visible = False
Sheets("REPORT").Select
ActiveCell.Font.Color = RGB(255, 0, 0)
ActiveCell.Font.Bold = True
MsgBox "One Or More Jobs Do Not Exist. Please Check for RED Highlighted
Job."
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
End Sub
Sub IMPORT_ALL_INFORMATION()
'Set variables
Dim file_in As Long
Dim strInput As Variant
'end setting variables
Sheets("REPORT").Select
Range("C2").Select
Do Until ActiveCell.Value = "" '//loop through each job
file_in = FreeFile 'next file number
strFileToOpen = strpathtofile & ActiveCell.Value & strFilename
Open strFileToOpen For Input As #file_in
Put_Data_In_Array (file_in)
Organize_Array_For_Print
Close #file_in ' close the file
file_in = file_in + 1
Sheets("REPORT").Select
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Judging by the title of your question this is what you need, but I am a little confused by your question:
sub MainSub()
FileOne = worksheets("SuperSecretHiddenSheet").range("A1").value
FileTwo = worksheets("SuperSecretHiddenSheet").range("A2").value
if bothfileExists(FileOne, FileTwo) = true then
'do stuff
end if
End Sub
function bothfileExists(ByRef FileOne as string, ByRef fileTwo as string) as boolean
if (dir(fileone) <> "" and dir(fileTwo) <> "") then
bothfileExists = True
else
bothfileExists = False
end if
end function

Excel VBA - Data connection opens workbook visibly sometimes

When I make a call to open a connection to another workbook, occasionally the workbook will open fully in Excel. I have ~15 data sets I pull using this method and I have not been able to identify a pattern. yesterday the refresh was quick and seamless and no workbooks visibly opened in Excel. Today 1 of 2 is opening in Excel.
Since I have users of varying experience with Excel, I would like to eliminate this possibly confusing behavior.
oCnC.Open "Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Data Source=" & Filename & ";Extended Properties=""Excel 12.0; HDR=YES;"";"
Example code:
sub Caller
Set dTabs = New Dictionary
Set dTabs("Cerner") = New Dictionary
dTabs("Cerner")("Query") = "Select Field1, Field2 from [Sheet1$]"
dTabs("Cerner")("Hidden") = 1
Call GetMasterTables("\\\Files\File1.xlsx", dTabs)
dTabs.RemoveAll
Set dTabs = New Dictionary
Set dTabs("SER") = New Dictionary
dTabs("SER")("Query") = "Select [1],F75 from [Sheet1$]"
dTabs("SER")("Hidden") = 1
Call GetMasterTables("\\Files\File2.xlsx", dTabs)
dTabs.RemoveAll
(Cleanup)
End Sub
Private Sub GetMasterTables(Filename As String, dTabset As Dictionary, ByRef wb As Workbook)
Dim oCnC As Connection
Dim rsC As Recordset
Dim rsE As Recordset
Dim lo As ListObject
Dim rngHome As Range
Set oCnC = New Connection
Set rsC = New Recordset
Set rsE = New Recordset
Dim ws As Worksheet
oCnC.Open "Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Data Source=" & Filename & ";" & _
"Extended Properties=""Excel 12.0; HDR=YES;"";"
rsC.ActiveConnection = oCnC
For Each i In dTabset
If SheetExists(i, wb) Then
Set ws = wb.Sheets(i)
ws.Visible = xlSheetVisible
Else
Set ws = wb.Sheets.Add(, wb.Sheets(wb.Sheets.count))
ws.Name = i
ws.Visible = xlSheetVisible
End If
Set rngHome = ws.Range("A1")
If RangeExists("Table_" & Replace(i, "-", "_"), ws) Then
Set lo = ws.ListObjects("Table_" & Replace(i, "-", "_"))
lo.DataBodyRange.Delete
Else
Set lo = ws.ListObjects.Add(, , , xlYes, rngHome)
lo.Name = "Table_" & Replace(i, "-", "_")
lo.DisplayName = "Table_" & Replace(i, "-", "_")
End If
If dTabset(i).Exists("Query") Then
rsC.Source = dTabset(i)("Query")
Else
rsC.Source = "Select * from [" & i & "$]"
End If
rsC.Open
rsC.MoveFirst
ws.Range(lo.HeaderRowRange.Offset(1, 0).address).Value = "hi"
lo.DataBodyRange.CopyFromRecordset rsC
rsC.MoveFirst
For Each j In lo.HeaderRowRange.Cells
j.Value = rsC.Fields(j.Column - 1).Name
Next j
rsC.Close
If dTabset(i).Exists("Hidden") Then
ws.Visible = xlSheetHidden
Else
ws.Visible = xlSheetVisible
End If
Next i
End Sub
Function SheetExists(ByVal shtName As String, Optional wb As Workbook) As Boolean
Dim sht As Worksheet
If wb Is Nothing Then Set wb = ActiveWorkbook
On Error Resume Next
Set sht = wb.Sheets(shtName)
On Error GoTo 0
SheetExists = Not sht Is Nothing
End Function
Function RangeExists(ByVal rngName As String, Optional ws As Worksheet) As Boolean
Dim rng As ListObject
If ws Is Nothing Then Set ws = ActiveWorksheet
On Error Resume Next
Set rng = ws.ListObjects(rngName)
On Error GoTo 0
RangeExists = Not rng Is Nothing
End Function
Update 1
Ah-ha! I have an update.
After the last test I had left the workbook open. When I came back to the computer after a few minutes there was a prompt up that the file was available for editing. Perhaps the intermittent behavior is due to the requested file being open by another user. I tested this theory by closing the workbook and then re-running the sub and it did not open the file in the app.
Update 2
Qualified my sheets references. Issue is still happening.
The issue is here (and anywhere else you're using Sheets without an object reference):
Set ws = Sheets(i)
ws.Visible = xlSheetVisible
Sheets is a global collection of the Application, not the Workbook that the code is running from. Track down all of these unqualified references and make them explicit:
Set ws = ThisWorkbook.Sheets(i)
You should also pass your optional parameter here:
'SheetExists(i)
'...should be...
SheetExists(i, ThisWorkbook)
I'm guessing the reason this is intermittent is that you're catching instances where the ADO connection has the other Workbook active, and your references aren't pointing to where they're supposed to.
In addition to the code review offered by #Comintern and #YowE3K I found a solution in the following:
Qualify my workbooks, and my sheets
Turn off screen updating (so the users can't see my magic)
Throw the book names in a dictionary before I do my update and close any extras that opened during the update.
Application.ScreenUpdating = False
For i = 1 To Application.Workbooks.count
Set dBooks(Application.Workbooks(i).Name) = i
Next i
Application.ScreenUpdating = False
Code from question
For i = 1 To Application.Workbooks.count
If dBooks.Exists(Application.Workbooks(i).Name) Then
dBooks.Remove (Application.Workbooks(i).Name)
Else
dBooks(Application.Workbooks(i).Name) = i
End If
Next i
For Each bookname In dBooks
Application.Workbooks(bookname).Close (False)
Next
Application.ScreenUpdating = True

Replacing an InputBox with a Userform (combobox)?

Forgive my noob-ery. Assistance greatly appreciated!!!!
Purpose of macro: Fill in form in Microsoft Word with text originating in an Excel workbook from a specified worksheet.
My problem: Selecting said worksheet to draw that information from and integrating result into my code. Using an InputBox for now but would like to replace said InputBox with a UserForm with a ComboBox- giving pre-set choice for worksheet names (these never change).
I've created the UserForm with the choices. How do I get my code to initialize it? And how do I get my code to use the result from the ComboBox?
Sub Ooopsie()
Dim objExcel As New Excel.Application
Dim exWb As Excel.Workbook
Dim exSh As Excel.Worksheet
Dim strSheetName As String
Dim strDefaultText As String
strDefaultText = "sheet name here"
strSheetName = InputBox( _
Prompt:="The sheet name is?", _
Title:="Sheet Name?", _
Default:=strDefaultText _
)
If strSheetName = strDefaultText Or strSheetName = vbNullString Then Exit Sub
Set exWb = objExcel.Workbooks.Open("path to worksheet")
ActiveDocument.Tables(1).Rows(3).Cells(1).Range.Text = "Blah: " & exWb.Sheets(strSheetName).Cells(3, 3)
ActiveDocument.Tables(1).Rows(5).Cells(1).Range.Text = "blah blah : " & Chr(11) & "blah: " & exWb.Sheets(strSheetName).Cells(3, 1)
ActiveDocument.Tables(1).Rows(6).Cells(1).Range.Text = "Date de réception : " & Chr(11) & "Date Received : " & exWb.Sheets(strSheetName).Cells(3, 2)
ActiveDocument.Tables(1).Rows(7).Cells(1).Range.Text = "blah d : " & Chr(11) & "Deadline: " & exWb.Sheets(strSheetName).Cells(3, 4)
exWb.Close
Set exWb = Nothing
End Sub
I refined your code some. This should get you started. I reworked it to make it easier for you to see what's going on. Instead of opening an existing workbook I create a new workbook. I left the Inputbox in there with some error handling so you get an idea of what you should do. The code now right from the MS Word table to Excel.
Option Explicit
Private Sub CommandButton1_Click()
Dim xlApp, xlWB, xlWS
Dim strSheetName As String, strDefaultText As String
Dim tbl As Table
strDefaultText = "Sheet1"
strSheetName = InputBox( _
Prompt:="The sheet name is?", _
Title:="Sheet Name?", _
Default:=strDefaultText)
Set xlApp = CreateObject("Excel.Application")
Set xlWB = xlApp.Workbooks.Add
On Error Resume Next
Set xlWS = xlWB.WorkSheets(strSheetName)
If Err.Number <> 0 Then
MsgBox "Worksheet [" & strSheetName & " Not Found", vbCritical, "Action Cancelled"
xlWB.Close False
xlApp.Quit
Exit Sub
End If
On Error GoTo 0
xlApp.Visible = True
On Error Resume Next
If ActiveDocument.Tables.Count > 0 Then
Set tbl = ActiveDocument.Tables(1)
xlWS.Cells(3, 3) = tbl.Rows(3).Cells(1).Range.Text
xlWS.Cells(3, 1) = tbl.Rows(5).Cells(1).Range.Text
xlWS.Cells(3, 2) = tbl.Rows(6).Cells(1).Range.Text
xlWS.Cells(3, 4) = tbl.Rows(7).Cells(1).Range.Text
End If
Set xlWB = Nothing
Set xlApp = Nothing
End Sub
It is worth noting that you can't instantiate Excel from MS Word like this without a reference to the Microsoft Excel 12.0 I think is?
Dim objExcel As New Excel.Application
Use this instead
Dim objExcel as Variant
Set objExcel = CreateObject("Excel.Application")
I know that this is not a chat forum but I am open to opinions and advice. I am only a hobbist after all.
Update here is how one way add items to a combobox
For Each xlSheet In xlWB.Worksheets
ComboBox1.AddItem xlSheet.Name
Next
So you've created a form called UserForm1.
You can display it as a modal dialog using the default instance:
UserForm1.Show vbModal
But a better practice would be to instantiate it instead - forms are objects after all, so you can New them up like any other class module:
Dim view As UserForm1
Set view = New UserForm1
view.Show vbModal
You can add properties to your form's code-behind to expose values the calling code can use:
Public Property Get SheetName() As String
SheetName = ComboBox1.Text
End Property
So you can now write a function that does this:
Private Function GetSheetName() As String
Dim view As UserForm1
Set view = New UserForm1
view.Show vbModal
GetSheetName = view.SheetName
End Function
Now you can replace your InputBox call with a call to this GetSheetName function!
Of course you'll want to handle the case where the user cancels out of the form, but that's beyond the scope of this question, and... it's been asked on this site already, just search and you'll find!