VBA Prompt user to choose Excel sheet - vba

I used Macro Recorder in Excel to record a series of tasks I need to automate. These tasks happen between two different Excel spreadsheets. I believe that the macro performs the code on the current worksheet, but right now the second sheet is hard coded. How do I prompt the user to choose an Excel sheet to reference to?
The workbook that is going to have the macro is the MasterHardwareDB & the file that needs to be replaced with a user input is Computer&DeploymentInfo_06_23_15_v3.xlsx
I was researching the filedialog object but I am not sure how to integrate here.
Sub AutomateCompare()
'
' AutomateCompare Macro
'
ActiveCell.Select
ActiveCell.FormulaR1C1 = _
"=INDEX('Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[scheduleddate],MATCH([ #HostName],'Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[computername],0))"
ActiveCell.Offset(1, 0).Range("MasterHardwareDB[[#Headers],[Name]]").Select
ActiveCell.FormulaR1C1 = _
"=INDEX('Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[scheduleddate],MATCH([#HostName],'Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[computername],0))"
ActiveCell.Offset(1, 0).Range("MasterHardwareDB[[#Headers],[Name]]").Select
ActiveWindow.SmallScroll ToRight:=-1
ActiveCell.Offset(-2, 1).Range("MasterHardwareDB[[#Headers],[Name]]").Select
ActiveCell.FormulaR1C1 = _
"=INDEX('Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[forecastdate],MATCH([#HostName],'Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[computername],0))"
ActiveWindow.SmallScroll ToRight:=1
ActiveCell.Offset(1, 0).Range("MasterHardwareDB[[#Headers],[Name]]").Select
ActiveWindow.SmallScroll ToRight:=-7
ActiveSheet.ListObjects("MasterHardwareDB").Range.AutoFilter Field:=9, _
Criteria1:="FALSE"
ActiveWindow.SmallScroll ToRight:=1
ActiveCell.Offset(4169, -4).Range("MasterHardwareDB[[#Headers],[Name]:[EmpID]]") _
.Select
ActiveCell.Offset(521, 1).Range("MasterHardwareDB[[#Headers],[Name]]").Select
ActiveWindow.SmallScroll ToRight:=-7
ActiveSheet.ListObjects("MasterHardwareDB").Range.AutoFilter Field:=5, _
Criteria1:="=Scheduled", Operator:=xlOr, Criteria2:="=To Be Scheduled"
ActiveCell.Offset(87, -8).Range("MasterHardwareDB[[#Headers],[Name]]").Select
ActiveWindow.SmallScroll ToRight:=8
End Sub

The easiest way to do this is
shtNum = InputBox("Enter the number of the sheet you want to use.")
With Sheets(shtNum)
Your code here
End With
Also, just so you know, macro recorder code contains a lot of junk. Here is a cleaned-up version of your code.
Sub AutomateCompare()
With ActiveSheet
'Change the ranges to what you need. Using activecell is usually dangerous
.Range("A1:A2").FormulaR1C1 = "=INDEX('Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[scheduleddate],MATCH([ #HostName],'Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[computername],0))"
.Range("B1").FormulaR1C1 = "=INDEX('Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[forecastdate],MATCH([#HostName],'Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[computername],0))"
.ListObjects("MasterHardwareDB").Range.AutoFilter Field:=9, Criteria1:="FALSE"
.ListObjects("MasterHardwareDB").Range.AutoFilter Field:=5, Criteria1:="=Scheduled", Operator:=xlOr, Criteria2:="=To Be Scheduled"
End With
End Sub
Edit: Here is code that opens another workbook
Sub AutomateCompare()
Dim fileBrowse As FileDialog
Dim shtNum As Integer
Set fileBrowse = Application.FileDialog(msoFileDialogOpen)
If fileBrowse.Show = True Then wbPath = fileBrowse.SelectedItems(1)
With Workbooks.Open(wbPath)
shtNum = InputBox("Enter the number of the sheet you want to use.")
With .Sheets(shtNum)
'Change the ranges to what you need. Using activecell is usually dangerous
.Range("A1:A2").FormulaR1C1 = "=INDEX('Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[scheduleddate],MATCH([ #HostName],'Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[computername],0))"
.Range("B1").FormulaR1C1 = "=INDEX('Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[forecastdate],MATCH([#HostName],'Computer&DeploymentInfo_06_23_15_v3.xlsx'!Table1[computername],0))"
.ListObjects("MasterHardwareDB").Range.AutoFilter Field:=9, Criteria1:="FALSE"
.ListObjects("MasterHardwareDB").Range.AutoFilter Field:=5, Criteria1:="=Scheduled", Operator:=xlOr, Criteria2:="=To Be Scheduled"
End With
End With
End Sub

Related

vba countif for duplicates when validating another data

I'm trying to copy data into new workbook and validate the data by removing duplicates keeping one cell value as the source.
All I wanted is the count of XD in the worksheet provided there are no duplicate Record locator.
Also I wanted the count to be in a msgbox. Can someone help ?
Sub openworkbook()
Workbooks.Open ("C:\Users\kjayachandiran\Desktop\ACUITY CF 1204-1210.xls")
Worksheets(2).Activate
Cells.Select
Selection.Copy
Workbooks.Open ("C:\Users\kjayachandiran\Desktop\New-Manjunath.xlsx")
Worksheets(1).Activate
Range("A1").Select
ActiveSheet.Paste
Workbooks(3).Save
Workbooks(2).Close
ActiveWorkbook.Activate
Worksheets(1).Activate
Cells(1, 1).Select
Range("A366655").Value = Application.WorksheetFunction.CountIf(Columns(9), "=" & "XD")
End Sub

How to reference an open Excel sheet that I don't know the name of?

Background:
I'm recording a macro in Excel that transfers data between three different workbooks that are all open at the same time (I'm recording it and then going into the code and fixing any bugs because I have zero experience with coding).
Problem:
Two of the workbooks will always be used while the third changes (ex. RFQ_1234, RFQ_1235). The macro works great, except each time I use it, I have to debug it and re-enter the name of the third workbook. How do I change my code so that it references the 3rd workbook without using a specific name?
Disclaimer:
I know .select is super slow, I don't care. It just needs to work. Also, I know very little about coding, so please explain even the smallest details.
Example of code:
Windows("RFQ_14446.xlsm").Activate
Range("J51").Select
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B1").Select
ActiveSheet.Paste
Windows("RFQ_14446.xlsm").Activate
Range("D27").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B2").Select
ActiveSheet.Paste
Windows("RFQ_14446.xlsm").Activate
Range("D5").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B3").Select
ActiveSheet.Paste
Changing as little of your code as possible (as requested!)...
Sub Tester()
Dim wbName As String
wbName = GetRfqWbName("RFQ_")
If Len(wbName) = 0 Then
MsgBox "Didn't find the RFQ workbook!"
Exit Sub
End If
Windows(wbName).Activate
Range("J51").Select
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B1").Select
ActiveSheet.Paste
Windows(wbName).Activate
Range("D27").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B2").Select
ActiveSheet.Paste
Windows(wbName).Activate
Range("D5").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B3").Select
ActiveSheet.Paste
End Sub
'get the name of the first workbook which begins with sName...
Function GetRfqWbName(sName As String) As String
Dim wb As Workbook
For Each wb In Workbooks
If wb.Name Like sName & "*" Then GetRfqWbName = wb.Name
Exit For
Next wb
End Function
EDIT: here's an improved version of the Tester sub above
Sub Tester2()
Dim wbName As String, shtSrc As Worksheet, shtDest As Worksheet
wbName = GetRfqWbName("RFQ_")
If Len(wbName) = 0 Then
MsgBox "Didn't find the RFQ workbook!"
Exit Sub
Else
'for example: you can substitute the sheet names instead
Set shtSrc = Workbooks(wbName).Sheets(1)
Set shtDest = Workbooks("Transfer Template.xlsm").Sheets(1)
End If
shtSrc.Range("J51").Copy shtDest.Range("B1")
shtSrc.Range("D27").Copy shtDest.Range("B2")
shtSrc.Range("D5").Copy shtDest.Range("B3")
End Sub
You can reference it by index or activesheet.
Dim ws as Excel.Worksheet
ws = Workbook.ActiveSheet
ws.Cell(A1).Value = "SomeValue"
Or you can use the index.
Set ws = ExcelApplication.Worksheets(1)

Create new Excel workbook and copy information with certain characteristics

I'm interning and was given an assignment in VBA, which I know very little about. I found code that is similar to the functions I need and have commented it with my best guesses. If you could help me understand what each piece does and where to replace the generic code with my own information, it would be greatly appreciated!
When patrons have an overdue record, they are sent a spreadsheet with a list of the records they must return and the records' attributes in the following columns.
I need to create a macro which will
Create a new workbook
Copy row 1 (headings)
Copy rows with the same User
Name the file “UniqueUserrecordsrecall.xlsx”
Save to C:\Users\xxx\Documents\xxx\xxx
Attributes: Records, Description, Client, Engagement, Days, Date, Type, LOS, Location, State, Final, User.
Workbook Name: RecordsRecall
Worksheet Name: Main
Sub details()
'Declaration
Dim thisWB As String
Dim newWB As String
thisWB = ActiveWorkbook.Name
'?
On Error Resume Next
Sheets("tempsheet").Delete
On Error GoTo 0
'CreateTempSheet
Sheets.Add
ActiveSheet.Name = "tempsheet"
'?
Sheets("Main").Select
If ActiveSheet.AutoFilterMode Then
Cells.Select
On Error Resume Next
ActiveSheet.ShowAllData
On Error GoTo 0
End If
'Copy User Column
Columns("L:L").Select
Selection.Copy
'Paste User Column in TempSheet
Sheets("tempsheet").Select
Range("A1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
'?
If (Cells(1, 1) = "") Then
LastRow = Cells(1, 1).End(xlDown).Row
If LastRow <> Rows.Count Then
Range("A1:A" & LastRow - 1).Select
Selection.Delete Shift:=xlUp
End If
End If
'Apply Unique Filters in Tempsheet
Columns("A:A").Select
Columns("A:A").AdvancedFilter Action:=xlFilterCopy, _
CopyToRange:=Range("B1"), Unique:=True
'?
Columns("A:A").Delete
Cells.Select
Selection.Sort _
Key1:=Range("A2"), Order1:=xlAscending, _
Header:=xlYes, OrderCustom:=1, _
MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
lMaxSupp = Cells(Rows.Count, 1).End(xlUp).Row
For suppno = 2 To lMaxSupp
Windows(thisWB).Activate
supName = Sheets("tempsheet").Range("A" & suppno)
If supName <> "" Then
Workbooks.Add
ActiveWorkbook.SaveAs supName
newWB = ActiveWorkbook.Name
Windows(thisWB).Activate
Sheets("Main").Select
Cells.Select
If ActiveSheet.AutoFilterMode = False Then
Selection.AutoFilter
End If
Selection.AutoFilter Field:=2, Criteria1:="=" & supName, _
Operator:=xlAnd, Criteria2:="<>"
LastRow = Cells(Rows.Count, 2).End(xlUp).Row
'Copy from TempSheet
Rows("1:" & LastRow).Copy
'Paste in newWB in TempSheet
Windows(newWB).Activate
ActiveSheet.Paste
'Save and Close newWB
ActiveWorkbook.Save
ActiveWorkbook.Close
End If
Next
'Delete TempSheet
Sheets("tempsheet").Delete
Sheets("Main").Select
If ActiveSheet.AutoFilterMode Then
Cells.Select
ActiveSheet.ShowAllData
End If
End Sub
Thanks for the help!
I am guessing this code does not achieve the effect you seek and you do not know where to start fixing it.
You are attempting too much in one go when you do not really know what you are doing.
I suggest you start by writing simple macros each of which achieves one step of your total requirement or adds one step to a previous macro. If you run into difficulties with one of these macros, you can post it with an explanation of what it does and what you want it to do. Questions with macros that isolate a single problem get answered very quickly. I would not know where to start debugging your current macro.
You have an AutoFilter but I cannot see how that selects the records of a patron with an overdue record. I think that is your first problem: how does the macro know which patron’s records are to be output? Could this be supName? Where has this come from?
Can you write a macro that creates an empty workbook and saves it with the desired name? Call that Macro1.
Write Macro2 by updating Macro1, to rename Sheet1 as “Overdue” or something more meaningful and then delete the other worksheets.
Can you write a macro that uses AutoFilter to select the required records? Write this as new macro Macro3.
Merge Macro2 and Macro3 and try copying the rows selected by AutoFilter to the new workbook. The statement SourceRange.Copy Destination:=FirstDestCell is likely to be easier to use than Copy and Paste.
I hope you can see why little macros which expand your knowledge one step at a time will be an easier path to your objective than trying to debug your current code.

How to prevent excel macro from pasting empty rows

I am trying design a macro in excel 2007. Here is what I need it to do:
When I enter an ID into a specific cell and run the macro, it will search for that ID in column A of a different workbook and autofilter. Then I need it to copy that data and paste it into the first workbook. My code is working, however when it is pasting a ton of extra rows beneath my data. How can I make it only copy and paste data and not empty rows? Here is my code:
Sub Medications()
'
' Medications Macro
'
' Keyboard Shortcut: Ctrl+m
'
Range("B1").Select
Workbooks.Open Filename:= _
"I:\Pharmacy\MTMP\2013\Master Lists\CMR Medication List.xlsx"
Range("A1").Select
ActiveCell.FormulaR1C1 = "Member ID"
Range("A1").Select
Selection.AutoFilter
ActiveSheet.Range(Selection, ActiveCell.SpecialCells(xlLastCell)).AutoFilter Field:=1, Criteria1:=Workbooks("Standardized Format Spreadsheet.xlsm").Worksheets("Demographics").Range("B1").Value
Cells.Select
Selection.Copy
Windows("Standardized Format Spreadsheet.xlsm").Activate
Sheets("Detailed Medication List").Select
Range("A1").Select
ActiveSheet.Paste
Windows("CMR Medication List.xlsx").Activate
Application.CutCopyMode = False
Application.DisplayAlerts = False
ActiveWorkbook.Close
Application.DisplayAlerts = True
Sheets("Demographics").Select
End Sub
It is always best to avoid selecting items whenever possible. You can use set a workbook to an object and access it through that.
The reason you are getting extra cells when you copy/paste is because you are selecting every cell and then copying. I suggest using only the used range so you don't pick up any extra cells.
Sub Medications()
Dim CMR_Wkbk As Workbook
Dim SFS_Wkbk As Workbook
Set SFS_Wkbk = Workbooks("Standardized Format Spreadsheet")
Set CMR_Wkbk = Workbooks.Open("I:\Pharmacy\MTMP\2013\Master Lists\CMR Medication List.xlsx")
Range("A1").Value = "Member ID"
ActiveSheet.UsedRange.AutoFilter Field:=1, Criteria1:=SFS_Wkbk.Sheets("Demographics").Range("B1").Value
ActiveSheet.UsedRange.Copy Destination:=SFS_Wkbk.Sheets("Detailed Medication List").Range("A1")
Application.DisplayAlerts = False
CMR_Wkbk.Close
Application.DisplayAlerts = True
Sheets("Demographics").Select
End Sub
Cells.Select
Selection.Copy
Cells.Select is selecting the entire content of the worksheet. I don't know, obviously, what you sheet looks like, but try selecting only the CurrentRegion - the equivalent of what is highlighted when you click in a cell and press Ctrl-A:
ActiveCell.CurrentRegion.Copy

Worksheet not being protected

I have the following code that copies one worksheet to another and pastes only values however the code that protects the sheet is not working? what am I doing wrong here?
Sub GetQuote()
Range("AK548").Select
Selection.Copy
Range("AK549").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Dim ws As Worksheet
Dim sDataOutputName As String
With Application
.Cursor = xlWait
.StatusBar = "Saving Quote & Proposal Sheet..."
.ScreenUpdating = False
' Copy specific sheets
' *SET THE SHEET NAMES TO COPY BELOW*
' Array("Sheet Name", "Another sheet name", "And Another"))
' Sheet names go inside quotes, seperated by commas
On Error GoTo ErrCatcher
Sheets(Array("Quote & Proposal")).Copy
On Error GoTo 0
' Paste sheets as values
' Remove External Links, Hperlinks and hard-code formulas
' Make sure A1 is selected on all sheets
For Each ws In ActiveWorkbook.Worksheets
ws.Cells.Copy
ws.[A1].PasteSpecial Paste:=xlValues
ws.Cells.Hyperlinks.Delete
Application.CutCopyMode = False
Cells(1, 1).Select
ws.Activate
Next ws
Cells(1, 1).Select
sDataOutputName = ThisWorkbook.Path & "\" & ThisWorkbook.Worksheets("Quote Questions").Range("AK545").Value & ".xlsx"
' Save it with the NewName and in the same directory as original
ActiveWorkbook.SaveCopyAs sDataOutputName
ActiveWorkbook.Protect Password:="12345"
ActiveWorkbook.Close SaveChanges:=False
.Cursor = xlDefault
.StatusBar = False
.ScreenUpdating = True
End With
Exit Sub
ErrCatcher:
MsgBox "Specified sheets do not exist within this workbook"
End Sub
You are protecting the workbook and setting the password, on the next line of code you closing the workbook but not saving the changes.
Your code is showing work book protection, not work sheet protection. If you want to protect the sheet, use worksheet protection:
ws.Protect Password:="12345", DrawingObjects:=True, Contents:=True, Scenarios:=True
'ADD AND REMOVE PARAMETERS AS YOU WANT THEM
I put in: ActiveSheet.Protect Password:="12345" just above the line of code: ActiveWorkbook.SaveCopyAs sDataOutputName and it worked!