Excel: How to program to have Excel read a cells contents then switch open a new worksheet? - vba

I'm very new to programming (1 day experience) and I am trying to build an interactive database but I keep running into issues with having a certain part work.
I want Excel to read the value selected in a certain cell and based on the value in that cell then have it open to a separate sheet, where I can begin another set of data entry.
I have tried a number of different options but as of now, my code looks like this:
Dim inputWks As Worksheet
Set inputWks = ("Input")
With inputWks
If Range("D13").contents = "Yes" Then
ActiveWorkbook.Sheets("Sheets2").activate
End If
End With
I know this is a simple question but I have not been able to have this work..

try this
Sub DoIt()
Dim inputWks As Worksheet
Set inputWks = ActiveWorkbook.Sheets("Input")
With inputWks
If Range("D13").Cells(1, 1) = "Yes" Then
ActiveWorkbook.Sheets("Sheets2").Activate
End If
End With
End Sub

Related

Excel VBA macro to copy certain columns to another Workbook

I need to copy certain columns of one spreadsheet to another spreadsheet.
In order to do so, I have a macro:
Sub Submit()
Dim sourceColumn As Range, targetColumn As Range
Set sourceColumn =
Workbooks("Submission_Form.xlsm").Worksheets("RGSheet").Columns("A")
Set myData = Workbooks.Open("I:\Projects\...\Macros\RG.csv")
Worksheets(1).Select
Worksheets(1).Range("A1").Select
Set targetColumn = Workbooks("RG.csv").Worksheets(1).Columns("A")
sourceColumn.Copy Destination:=targetColumn
End Sub
However, when the cursor hits targetColumn, it gives error:
Run-time error '9':
Subscript out of range
For the sake of simplicity, I have put RG.csv in the same folder as Submission_Form.xlsm. So I am really confused why is it giving error.
I would also like to know how to handle if the RG.csv is located in another directory.
The error is probably because Submission_Form.xlsm isn't opened(?). Your code looks a little inconsistent. Maybe just open both source and destination, and copy the column. Something like this?
Option Explicit
Sub Submit()
Dim vSourceWorkbook As Workbook
Dim vDestinationWorkbook As Workbook
Set vSourceWorkbook = Workbooks.Open("Submission_Form.xlsm")
Set vDestinationWorkbook = Workbooks.Open("I:\Projects\...\Macros\RG.csv")
vSourceWorkbook.Worksheets("RGSheet").Range("A:A").Copy Destination:=vDestinationWorkbook.Worksheets(1).Range("A:A")
End Sub

Excel VBA: Generate N Number of Sheets Based on Cel Value

I want to create a macro that will generate N number of template sheets based on the value of a cel. For example, User inputs 4 into this particular cell and it subsequently generates 4 new sheets in the workbook of this template.
I've searched all through Stack overflow for a question that matches mine but none do. The closest I found was this and although the inital headline question asks generally the same question, when going into detail the user who asked this changes their question to"insert number of cells based on a cell value". Still I used this as a starting point.
Sub CreateSheets()
Dim facilitiesNum As Integer
facilitiesNum = Range("B2").Value
sheetsNeeded = facilitiesNum
With ThisWorkbook.Sheets
For i = sheetsNeeded To Master.Range("B2").Value2
.Item("TemplateSheet").Copy After:=.Item(.Count)
.Item(.Count).Name = sheetsNeeded
Next
End With
End Sub
I am new to VBA so I could be very off syntax-wise but in pseudocode my goal is
numberOfTemplates = cell value
numSheetsNeeded = numberOfTemplates
For i = numSheetsNeeded To NumOfTemp:
create sheets using numSheetsNeeded as reference for how many need to be
generated
How do I go about doing this?
If you just want to add new sheets this should be enough
Sub CreateSheets()
Dim facilitiesNum As Long
facilitiesNum = Range("B2").Value
With ThisWorkbook.Sheets
For i = 1 To facilitiesNum
.Item("TemplateSheet").Copy After:=.Item(.Count)
.Item(.Count).Name = i
Next i
End With
end sub

Can I create a Jump table in VBA for Excel?

I wrote a simple translator / parser to process an EDI (830) document using multiple Select Case statements to determine the code to be executed. I’m opening a file in binary mode and splitting the document into individual lines, then each line is split into the various elements where the first element of every line has a unique segment identifier.
My code works perfectly as written. However, Select Case requires checking every Case until a match is found or the Case Else is executed. I’ve sequenced the Case statements in such a manner that the segments that appear most frequently (as in the case of loops), are placed first to minimize the number of "checks before code is actually executed.
Rather than using multiple Select Cases, I would prefer to determine an index for the segment identifier and simply call the appropriate routine using that index. I’ve used jump tables in C and Assembler and anticipated similar functionality may be possible in VBA.
You can do jump tables in VBA by using the Application.Run method to call the appropriate routine by name. The following code demonstrates how it works:
Public Sub JumpTableDemo()
Dim avarIdentifiers() As Variant
avarIdentifiers = Array("Segment1", "Segment2")
Dim varIdentifier As Variant
For Each varIdentifier In avarIdentifiers
Run "Do_" & varIdentifier
Next varIdentifier
End Sub
Public Sub Do_Segment1()
Debug.Print "Segment1"
End Sub
Public Sub Do_Segment2()
Debug.Print "Segment2"
End Sub
You can do this in Excel VBA, following the example below:
The example assumes you have split your EDI document into two columns, one with the 'processing instruction' and one with the data that instruction will process.
The jump table is to the right i.e. a distinct list of the 'processing instructions' plus a name of a Sub-routine to run for each instruction.
The code is:
Option Explicit
Sub JumpTable()
Dim wsf As WorksheetFunction
Dim ws As Worksheet
Dim rngData As Range '<-- data from your file
Dim rngCell As Range '<-- current "instruction"
Dim rngJump As Range '<-- table of values and sub to run for value
Dim strJumpSub As String
Dim strJumpData As String
Set wsf = Application.WorksheetFunction '<-- just a coding shortcut
Set ws = ThisWorkbook.Worksheets("Sheet1") '<-- change to your worksheet
Set rngData = ws.Range("A2:A17") '<-- change to your range
Set rngJump = ws.Range("E2:F4") '<-- change to your circumstances
For Each rngCell In rngData
strJumpSub = wsf.VLookup(rngCell.Value, rngJump, 2, False) '<-- lookup the sub
strJumpData = rngCell.Offset(0, 1).Value '<-- get the data
Application.Run strJumpSub, strJumpData '<-- call the sub with the data
Next rngCell
End Sub
Sub do_foo(strData As String)
Debug.Print strData
End Sub
Sub do_bar(strData As String)
Debug.Print strData
End Sub
Sub do_baz(strData As String)
Debug.Print strData
End Sub
Make sure that you have written a Sub for each entry in the jump table.

Two issues - saving changes in an instantiated workbook, and activating other workbooks

I have two spreadsheets; I'll call them spreadsheet 1 and spreadsheet 2. Spreadsheet one has a function which generates days of the month, and if it's at the end of the month, it is trying to call the module/sub in spreadsheet 2. This is to generate both "daily" reports and "monthly" reports.
At this point, there are two errors: the first is when I am trying to save the new instance of spreadsheet 2 that I created. The error is that it asks to save the workbook in a macro-free format. I simply want to save it! Not to make any changes to formatting. I am not even sure that it is trying to save changes to the instantiated book object.
the second is in spreadsheet 2, even though I set it to be active sheet (I think), the activesheet still comes up as the worksheet on spreadsheet 1 that runs the macro in the first place.
Any help is appreciated.
Option Explicit
Public Function LastWeekOfMonth() As Boolean
'finds the current date
Dim CurrentDate As Date
CurrentDate = CDate(ActiveSheet.Cells(FIRST_DATA_ROW, 1))
'find filepath and filename of the monthly documentation file
Dim mFilePath As String
Dim mFileName As String
mFilePath = "F:\Project Sweep\Kim Checklist\Barry Polinsky\Brathwaite, Tamika\"
mFileName = Cells(3, 4) & ".m_d.xlsm"
'if it is the last week of the month, write a monthly report, and return true to continue with the face to face paperwork
If (31 - Day(CurrentDate)) <= 7 Then
'write a monthly report
Dim app As New Excel.Application
Dim book As Excel.Workbook
' app.Visible = False 'Visible is False by default, so this isn't necessary
Set book = app.Workbooks.Add(mFilePath & mFileName)
'run the subroutine CheckSpreadsheet in module WriteReport in target book
app.Run "'" & mFilePath & mFileName & "'!" & "WriteReport" & ".CheckSpreadsheet", book
' CheckSpreadsheet (book)
'error next line
book.Save
book.Close
app.Quit
Set app = Nothing
LastWeekOfMonth = True
'if it is not, simply continue with the face to face paperwork
Else
LastWeekOfMonth = False
End If
End Function
In the target worksheet, in module WriteReport, subroutine CheckSpreadsheet, the following code is located.
Option Explicit
Public Sub CheckSpreadsheet(wbook As Excel.Workbook)
Set wosheet = wbook.Sheets("Monthly")
wosheet.Cells(5, 5) = "Hello world!"
End Sub
Don't need to have another instance of Excel, the property to hide a workbook is Windows, in order to hide the excel windows used by the workbook. Also bear in mind that a workbook can have more than one window.
If you are sure that the workbook you want to hide has only one window use this line:
Workbooks("WbkName").Windows(1).Visible = False
If the workbook has several windows use this procedure:
Sub Wbk_Hide()
Dim wbk As Workbook, wdw As Window
Set wbk = Workbooks("WbkName") 'Update as required
For Each wdw In wbk.Windows
wdw.Visible = False
Next
End Sub
I believe this changes the scope of your procedures, let me know otherwise.

How to add a new spreadsheet with VBA-Code, using VBA

I am creating a macro and part of the macros function is to make VBA create a new spreadsheet. Because of the nature of distribution the name will change. I need to add code to this spreadsheet. Is there anyway I can do this?
Jook has already explained how it works. I will take it a step further.
The syntax of adding a worksheet is
expression.Add(Before, After, Count, Type)
If you check inbuilt Excel's help then you can see what Before, After, Count, Type stands for
FROM EXCEL"S HELP
Parameters (All 4 parameters are Optional)
Before - An object that specifies the sheet before which the new sheet is added.
After - An object that specifies the sheet after which the new sheet is added.
Count - The number of sheets to be added. The default value is one.
Type - Specifies the sheet type. Can be one of the following XlSheetType constants: xlWorksheet, xlChart, xlExcel4MacroSheet, or xlExcel4IntlMacroSheet. If you are inserting a sheet based on an existing template, specify the path to the template. The default value is xlWorksheet.
Once the sheet is created then you need to use .insertlines to create the relevant procedure and to also embed the code that you want to run.
NOTE - IMP: If you want the code to embed code in the VBA project, you need to ensure that you have "Trust Access to the VBA Project Object Model" selected. See snapshot.
Here is an example where I am creating a sheet and then embedding a Worksheet_SelectionChange Code which will display a message "Hello World"
CODE - TRIED AND TESTED
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim nLines As Long
Dim VBP As Object, VBC As Object, CM As Object
Dim strProcName As String
Set ws = Worksheets.Add
Set VBP = ThisWorkbook.VBProject
Set VBC = VBP.VBComponents(ws.Name)
Set CM = VBC.CodeModule
strProcName = "Worksheet_SelectionChange"
With ThisWorkbook.VBProject.VBComponents( _
ThisWorkbook.Worksheets(ws.Name).CodeName).CodeModule
.InsertLines Line:=.CreateEventProc("SelectionChange", "Worksheet") + 1, _
String:=vbCrLf & _
" Msgbox ""Hello World!"""
End With
End Sub
This is how the new sheet code area looks once you run the above code.
the following code will add you a spreadsheet.
Public Sub Workbook_Add()
Dim wks As Worksheet
Set wks = ThisWorkbook.Worksheets.Add(, , 1, xlWorksheet)
With wks
'set codename of wks
ThisWorkbook.VBProject.VBComponents(.CodeName).Name = "tblWhatever"
'set tablename of wks
.Name = "whatever"
'add code (untested demo)
'ThisWorkbook.VBProject.VBComponents(.CodeName).CodeModule.InsertLines 1, "Option Explicit"
'add code (as of example from excel-help)
'Application.VBE.CodePanes(1).CodeModule.InsertLines 1, "Option Explicit"
End With
End Sub
If you need to add VBA-Code to this specific spreadsheet, you should further inspect the VBProject object - look for CodeModule and then i.e. InsertLines.
A further hint for you - I would try to use the CodeNames of your tables. It is less likely to be changed - BUT it might be not that comfortable to use in your code at first. I had to get used to it, but for me it has many advantages against using a tables name.
Hope this helps ;)
The default .Add method adds a sheet at the start of the list. Often you want to add it at the end before adding the code lines, as explained by Siddarth Rout. To do that anywhere you can use:
ActiveWorkbook.Worksheets.ADD After:=ActiveWorkbook.Sheets(ActiveWorkbook.Worksheets.Count)
It is easier to read if you have defined and set WB:
Dim WB as Excel.workbook
Set WB = ActiveWorkbook
WB.Sheets.ADD After:=WB.Sheets(WB.Sheets.Count)
Set VBC = ActiveSheet 'If using in Siddarth Rout's code above
Sheets and Worksheets are interchangeable, as illustrated.