VBA VLOOKUP, instead of 'book1', as a string - excel

EDIT: Posted full userform code
this is my userform
What I need to do, is load a csv, and a second csv essentially with updated price. I'm then using vlookup to match data. I just cant get my code to compile while I try to target MyVal2 with Module3.
Book1 is a remnant from recording a macro testing how it'd work.
Public MyVal1 As String 'AUS URL'
Public MyVal2 As String 'scrape'
Private Sub CommandButton1_Click()
Workbooks.OpenText Filename:=(MyVal1)
Workbooks.OpenText Filename:=(MyVal2)
Application.Run "Module2.AuscompDataSheet"
Application.Run "Module3.AuscompDataSheet"
ActiveWorkbook.Save
ActiveWorkbook.Close
End Sub
Private Sub CommandButton2_Click()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = False
' Set the title of the dialog box.
.Title = "Please select the file."
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "All Files", "*.*"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
TextBox1 = .SelectedItems(1)
End If
End With
End Sub
Private Sub CommandButton3_Click()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = False
' Set the title of the dialog box.
.Title = "Please select the file."
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "All Files", "*.*"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
TextBox2 = .SelectedItems(1)
End If
End With
End Sub
Private Sub TextBox1_Change()
MyVal1 = UserForm1.TextBox1.Value
End Sub
Private Sub TextBox2_Change()
MyVal2 = UserForm1.TextBox2.Value
End Sub
Private Sub UserForm_Click()
End Sub
Private Sub UserForm_Initialize()
End Sub
MODULE 3:
ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[-3],[MyVal2]Sheet1!R2C1:R5C3,3,FALSE)"
Range("D2").Select
Selection.AutoFill Destination:=Range("D2:D7"), Type:=xlFillDefault
Range("D2:D7").Select

I think the problem is that you are assigning the value of the variables myVal1 and MyVal2 by changing the assignment in the CommandButton1 instead of doing it in the textboxes and at the beginning of the code as a public declaration.
Private Sub CommandButton1_Click()
Dim MyVal2, MyVal1 as string
MyVal2 = UserForm1.TextBox2.Value
MyVal1 = UserForm1.TextBox1.Value
Workbooks.OpenText Filename:=(MyVal1)
Workbooks.OpenText Filename:=(MyVal2)
call AuscompDataSheet
call AuscompDataSheet
ActiveWorkbook.Save
ActiveWorkbook.Close
End Sub

Related

Open file, select sheet and copy it to file with macro

this is my first post. I would like to have a code which would let user to choose file with filedialog then populate sheet names from the file to userform and copy selected sheet to workbook with the code.
Private wbSource As Workbook
Private wsSource As Worksheet
Private Sub UserForm_Initialize()
Dim I As Long
Dim filedlg As FileDialog
Set filedlg = Application.FileDialog(msoFileDialogFilePicker)
With filedlg
.Title = "Please select a file to list Sheets from"
.InitialFileName = ThisWorkbook.Path
.ButtonName = "Select"
If .Show <> -1 Then End
End With
Set wbSource = Workbooks.Open(filedlg.SelectedItems(1))
Me.ComboBox1.Clear
With wbSource
For I = 1 To .Worksheets.Count
Me.ComboBox1.AddItem Sheets(I).Name
Next
End With
End Sub
Private Sub ComboBox1_Click()
Set wsSource = wbSource.Worksheets(Me.ComboBox1.Value)
wsSource.Copy ThisWorkbook.Sheets(Sheets.Count)
wbSource.Close SaveChanges:=False
Unload Me
End Sub
The code is working until excel tries copy the sheet, there is a Run-time error 9 - Subscript out of range. Did I declare variables wrongly?

VBA Use variable value across modules

I'm trying to use the name of a workbook which I set in module 1, across other private modules but I'm getting different errors depending on how I set it up. I added comments in the code that explain what happens in the different scenarios.
Option Explicit
Sub TestSharedVars()
CopyCellsthenClose
OpenNewWksheet (AlphaExportBook)
' *** Like this
' OpenNewWksheet (AlphaExportBook) I get "Error Variable not defined"
' *** Like this
' OpenNewWksheet I get "Error Argument not optional"
CloseWkbook
End Sub
Private Sub CopyCellsthenClose()
Dim AlphaExportBook As Workbook
Dim theRows
Dim theColumns
With ActiveSheet.UsedRange
theRows = .Rows.Count
theColumns = .Columns.Count
Range(Cells(1, 1), Cells(theRows, theColumns)).Select
End With
Selection.Copy
Set AlphaExportBook = ActiveWorkbook
End Sub
Private Sub OpenNewWksheet()
'******************************
' Open the File Dialog
'******************************
Dim ReversionWBook As Workbook
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
.Execute
If (.SelectedItems.Count = 0) Then
MsgBox "User Cancelled Operation"
' GoTo EndofInstructions
Else
End If
End With
ActiveWorkbook.Activate
Set ReversionWBook = ActiveWorkbook
End Sub
Private Sub CloseWkbook(AlphaExportBook As Workbook)
'**********************************
' Close Alpha Export WorkBook
'**********************************
AlphaExportBook.Activate
Application.DisplayAlerts = False
AlphaExportBook.Close SaveChanges:=False
Application.DisplayAlerts = True
End Sub
Firstly, you shouldn't be getting an "Argument not optional" error when calling OpenNewWksheet because that subroutine is not expecting arguments. You would get that error trying to call CloseWkbook without specifying a parameter, because that subroutine expects a Workbook object to be passed to it.
The easiest way to make the workbook available to all subroutines is to declare the variable with module-level scope, e.g.
Option Explicit
Dim AlphaExportBook As Workbook
Sub TestSharedVars()
CopyCellsthenClose
OpenNewWksheet
CloseWkbook
End Sub
Private Sub CopyCellsthenClose()
Dim theRows
Dim theColumns
With ActiveSheet.UsedRange
theRows = .Rows.Count
theColumns = .Columns.Count
'Note - the following line won't do what you expect unless
' UsedRange starts at cell A1
Range(Cells(1, 1), Cells(theRows, theColumns)).Select
End With
Selection.Copy
Set AlphaExportBook = ActiveWorkbook
End Sub
Private Sub OpenNewWksheet()
'******************************
' Open the File Dialog
'******************************
Dim ReversionWBook As Workbook ' Does this need to be module-level scope too?
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
.Execute
If .SelectedItems.Count = 0 Then
MsgBox "User Cancelled Operation"
End If
End With
'ActiveWorkbook.Activate ' This is redundant - the ActiveWorkbook is already active
Set ReversionWBook = ActiveWorkbook
End Sub
Private Sub CloseWkbook()
'**********************************
' Close Alpha Export WorkBook
'**********************************
'You don't need to activate the workbook before you close it
'AlphaExportBook.Activate
Application.DisplayAlerts = False
AlphaExportBook.Close SaveChanges:=False
Application.DisplayAlerts = True
End Sub
Alternatively, you could pass the workbook object between subroutines as follows:
Option Explicit
Sub TestSharedVars()
'Dimension object to have scope only within this subroutine, but we
' will pass a reference to this object to the other subroutines that
' need to reference it
Dim AlphaExportBook As Workbook
CopyCellsthenClose AlphaExportBook
OpenNewWksheet
CloseWkbook AlphaExportBook
End Sub
Private Sub CopyCellsthenClose(wb As Workbook)
Dim theRows
Dim theColumns
With ActiveSheet.UsedRange
theRows = .Rows.Count
theColumns = .Columns.Count
'Note - the following line won't do what you expect unless
' UsedRange starts at cell A1
Range(Cells(1, 1), Cells(theRows, theColumns)).Select
End With
Selection.Copy
Set wb = ActiveWorkbook
End Sub
Private Sub OpenNewWksheet()
'******************************
' Open the File Dialog
'******************************
Dim ReversionWBook As Workbook ' Does this need to be module-level scope too?
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
.Execute
If .SelectedItems.Count = 0 Then
MsgBox "User Cancelled Operation"
End If
End With
'ActiveWorkbook.Activate ' This is redundant - the ActiveWorkbook is already active
Set ReversionWBook = ActiveWorkbook
End Sub
Private Sub CloseWkbook(wb As Workbook)
'**********************************
' Close Alpha Export WorkBook
'**********************************
'You don't need to activate the workbook before you close it
'wb.Activate
Application.DisplayAlerts = False
wb.Close SaveChanges:=False
Application.DisplayAlerts = True
End Sub

Hide pictures compression dialog box in VBA (Excel 2010)

I use a macro to automatically compress pictures in Excel 2010, the macro opens a dialog and sendkeys, and final users can see it (for half a second), i want to hide it. Please help !
This is my macro:
Sub compression()
Application.SendKeys "%w~"
Application.CommandBars.ExecuteMso "PicturesCompress"
End Sub
I already tried:
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
But they don't seem to work.
#TomPreston
Here's my whole code, i want users to double click on type of cells to insert pictures in comments but the pictures must be compressed to keep the file fit !
I ALSO have problems with sendkeys and num lock, if someone can help me on this (see below):
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Not Intersect(Target, [v:v]) Is Nothing Then
Application.ScreenUpdating = False
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.InitialFileName = CurDir
.Filters.Clear
.Filters.Add Description:="Images", Extensions:="*.png;*.jpg;*.jpeg;*.gif", Position:=1
.Title = "Choose image"
If .Show = -1 Then TheFile = .SelectedItems(1) Else TheFile = 0
End With
If TheFile = 0 Then
MsgBox ("No image selected")
Exit Sub
End If
ActiveCell.ClearComments
Selection.AddComment
PreviousCell = ActiveCell.Address
ActiveCell.Comment.Shape.Fill.UserPicture TheFile
NumLockState = GetKeyState(VK_NUMLOCK)
Application.SendKeys "%a~"
Application.CommandBars.ExecuteMso "PicturesCompress"
If NumLockState <> GetKeyState(VK_NUMLOCK) Then
Application.SendKeys ("%{Numlock}"), True
End If
ActiveCell.Comment.Visible = True
CommentAdded = True
Application.ScreenUpdating = True
End If
End Sub
Users can change de size of the picture and after the selection change, the comment is hidden.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If CommentAdded = True Then
Range(PreviousCell).Comment.Visible = False
PreviousCell = ""
CommentAdded = False
End If
End Sub
And these are the variables:
Public CommentAdded As Boolean
Public PreviousCell As String
Public Const VK_NUMLOCK = &H90
Public Declare Function GetKeyState Lib "user32" _
(ByVal nVirtKey As Long) As Long
If you just want to hide the flicker effect, use this:
Sub compression()
Application.ScreenUpdating = False
Application.SendKeys "%w~" Application.CommandBars.ExecuteMso "PicturesCompress"
Application.ScreenUpdating = True
End Sub

"object required" error while selecting a file and displaying the path

I am trying to have a browse button on an excel sheet by clicking which i can select a file and the path of the selected file will get displayed in a textbox on the same excel sheet.This is the code i have tried:
Dim File_Path As Long
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
GetFolder = .SelectedItems(1)
TextBox1.Value = GetFolder
End With
End Sub
when i run the code,i am able to select a file but then i am getting a runtime error "object required" and the line
TextBox1.Value = GetFolder
is getting highlighted.can anyyone please help me with this.thank you.
Error suggest that you don't have any TextBox object in the Activesheet or Object reference is not complete.
Possible solution (when talking about ActiveSheet):
ActiveSheet.TextBox1.Value = GetFolder
or when talking about any other sheet:
Sheets("NameOfTheSheetHere").TextBox1.Value = GetFolder
Misunderstood the question.
Here is another way.
Replace
TextBox1.Value = GetFolder
with
ActiveSheet.Shapes("Textbox1").OLEFormat.Object.Object.Text = getfolder
In a more structured way...
Sub Button2_Click()
Dim File_Path As Long
Dim shp As Shape
Set shp = ActiveSheet.Shapes("Textbox1")
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
getfolder = .SelectedItems(1)
shp.OLEFormat.Object.Object.Text = getfolder
End With
End Sub
Also instead of Application.FileDialog(msoFileDialogOpen) you may use the inbuilt Application.GetOpenFilename
Private Sub CommandButton1_Click()
Dim Ret
Ret = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
If Ret <> False Then _
ActiveSheet.Shapes("Textbox1").OLEFormat.Object.Object.Text = getfolder
End Sub
BTW change "Excel Files (*.xls*), *.xls*" to "All Files (*.*), *.*" if you want to show all files and not just Excel Files.

Cell Locking on Save if data has been entered

This is a follow up from this question, Lock Cells after Data Entry. I have progressed from asking that question but encountered more problems so felt I should ask a new question. The workbook is edited by multiple users. To prevent tampering with previous data the cells are locked once data has been entered and the file saved.
I have a couple of small bugs in the code:
If the user chooses to SaveAs then tries to save over an existing file the usual ' Do you want to replace this file?' dialog appears. If the user selects no there is a run time error. I have highlighted where the error is in the code below but I am unsure how to fix it.
If the user has entered data then tries to exit and save the file using the save dialog box that appears on close the file is saved but the data is not locked. I have been trying to call my main code to lock the cells upon an exit save but I keep encountering argument not optional errors.
Here is the full code:
Option Explicit
Const WelcomePage = "Macros"
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
'Written by Alistair Weir (alistair.weir#communitypharmacyscotland.org.uk, http://alistairweir.blogspot.co.uk/)
Dim ws As Worksheet
Dim wsActive As Worksheet
Dim vFilename As Variant
Dim bSaved As Boolean
'Turn off screen updating
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
'Record active worksheet
Set wsActive = ActiveSheet
'Prompt for Save As
If SaveAsUI = True Then
MsgBox "Are you sure you want to save? Data entered cannot be edited once the file has been saved. Press cancel on the next screen to edit your data or continue if you are sure it is correct.", vbCritical, "Are you sure?"
vFilename = Application.GetSaveAsFilename("", fileFilter:="Excel Files (*.xls), *.xls")
If CStr(vFilename) = "False" Then
bSaved = False
Else
'Save the workbook using the supplied filename
Call HideAllSheets
'--> The vFilename Variant in the next line is the problem **
'--> when trying to overwrite an existing file **
ThisWorkbook.SaveAs vFilename
Application.RecentFiles.Add vFilename
Call ShowAllSheets
bSaved = True
End If
Else
'Save the workbook, prompt if normal save selected not save As
Call HideAllSheets
If MsgBox("Are you sure you want to save? Data entered cannot be edited after saving", vbYesNo, "Save?") = vbYes Then
ThisWorkbook.Save
Call ShowAllSheets
bSaved = True
Else
Cancel = True
End If
Call ShowAllSheets
End If
'Restore file to where user was
wsActive.Activate
'Restore screen updates
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
'Set application states appropriately
If bSaved Then
ThisWorkbook.Saved = True
Cancel = True
Else
Cancel = True
End If
'Lock Cells before save if data has been entered
Dim rpcell As Range
With ActiveSheet
If bSaved = True Then
.Unprotect Password:="oVc0obr02WpXeZGy"
.Cells.Locked = False
For Each rpcell In ActiveSheet.UsedRange
If rpcell.Value = "" Then
rpcell.Locked = False
Else
rpcell.Locked = True
End If
Next rpcell
.Protect Password:="oVc0obr02WpXeZGy"
Else
MsgBox "The LogBook was not saved. You are free to edit the RP Log again", vbOKOnly, "LogBook Not Saved"
End If
End With
End Sub
Private Sub Workbook_Open()
Application.ScreenUpdating = False
Call ShowAllSheets
Application.ScreenUpdating = True
ThisWorkbook.Saved = True
End Sub
'Called to hide all the sheets but enable macros page
Private Sub HideAllSheets()
Dim ws As Worksheet
Worksheets(WelcomePage).Visible = xlSheetVisible
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name = WelcomePage Then ws.Visible = xlSheetVeryHidden
Next ws
Worksheets(WelcomePage).Activate
End Sub
'Called to show the data sheets when macros are enabled
Private Sub ShowAllSheets()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name = WelcomePage Then ws.Visible = xlSheetVisible
Next ws
Worksheets(WelcomePage).Visible = xlSheetVeryHidden
End Sub
Thanks :)
Edit
For now I am solving problem 2 by bypassing excel's default 'do you want to save?' by doing this:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If MsgBox("Are you sure you want to quit? Any unsaved changes will be lost.", vbYesNo, "Really quit?") = vbNo Then
Cancel = True
Else
ThisWorkbook.Saved = True
Application.Quit
End If
End Sub
I am open to suggestions of a better way and still haven't solved the first problem.
One possibility is to write your own confirmations in a save function, like so:
Private Function SaveSheet(Optional fileName) As Boolean
HideAllSheets
If fileName = "" Then
ThisWorkbook.Save
SaveSheet = True
Else
Application.DisplayAlerts = False
If Dir(fileName) <> "" Then
If MsgBox("Worksheet exists. Overwrite?", vbYesNo, "Exists") = vbNo Then Exit Function
End If
ThisWorkbook.saveAs fileName
SaveSheet = True
Application.DisplayAlerts = True
End If
ShowAllSheets
End Function
And change your original code to something like:
If SaveAsUI Then
If MsgBox( _
"Are you sure you want to save? Data entered cannot be edited once the file has been saved. " & _
"Press cancel on the next screen to edit your data or continue if you are sure it is correct.", _
vbYesNo, "Are you sure?" _
) = vbYes Then
vFilename = Application.GetSaveAsFilename("", fileFilter:="Excel Files (*.xls), *.xls")
If vFilename <> "" Then
If SaveSheet(vFilename) Then bSaved = True
End If
End If
Else
If MsgBox( _
"Are you sure you want to save? Data entered cannot be edited after saving", _
vbYesNo, "Save?" _
) = vbYes Then
If SaveSheet("") Then bSaved = True
End If
End If
I've not fully tested the above, but it should give you some ideas.

Resources