Macro button to switch to previous sheet - vba

So I've been playing around with macros and buttons and I am trying to make a button, that on clicking it, it will go to the previous sheet (they are names Day 1, 2, 3, etc...) so I figure this shouldn't be too difficult!
Here is the code that I have got so far:
Sub Previous_Day()
Worksheets("Day " & (sheetNum - 1)).Visible = xlSheetVisible
Worksheets("Day " & (sheetNum - 1)).Activate
Worksheets("Day " & sheetNum).Visible = xlSheetHidden
sheetNum = sheetNum - 1
End Sub
I get an error when I click the button with this which says "subscript out of range", I'm not entirely sure why this is happening, I globally define sheetNum in the 'This Workbook' module, and I shall show that code below:
Public sheetNum As Integer
Private Sub Workbook_Open()
Dim thisSheet As Worksheet
Dim sh As Worksheet
Dim start As Worksheet
Dim shName As String
Dim lastSheet As String
'name of the sheet template
shName = "Food Diary Template.xltm"
lastSheet = "Food Diary Last Entry.xltm"
Set start = Worksheets(1)
With start
If .Range("A1") = "" Then
.Range("A1") = Date
ActiveSheet.Shapes("Button 5").Select
Selection.Delete
.Range("B4").Select
End If
End With
Worksheets(Sheets.Count).Activate
'#### I like to use variables for worksheets:
Set thisSheet = ThisWorkbook.ActiveSheet
'Insert sheet template
With thisSheet
If .Range("A1") < Date Then
ActiveSheet.Buttons.Add(436.5, 104.25, 58.5, 18.75).Select
Selection.OnAction = "nextDay_Click"
ActiveSheet.Shapes("Button 1").Select
Selection.Characters.Text = "Button 1"
With Selection.Characters(start:=1, Length:=8).Font
.Name = "Calibri"
.FontStyle = "Regular"
.Size = 11
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
End With
ActiveSheet.Shapes("Button 1").Select
Selection.Characters.Text = "Next Day"
With Selection.Characters(start:=1, Length:=8).Font
.Name = "Calibri"
.FontStyle = "Regular"
.Size = 11
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
End With
.Range("B4").Select
Set sh = Sheets.Add(Type:="C:\Users\edawes\AppData\Roaming\Microsoft\Templates\" & lastSheet, _
after:=Sheets(Sheets.Count))
'#### Put today's date in the new sheet:
sh.Range("A1") = Date
sh.Name = "Day " & Worksheets.Count
'Worksheets(sh).Active
sh.Range("B4").Select
'#### Hide the old sheet
.Visible = xlSheetHidden
End If
End With
sheetNum = Sheets.Count
End Sub
This bit works fine as I want it to, but it's the sheetNum that I'm not sure about, have I done it right? I want it to be the total number of sheets when the file is opened and then when the button is pressed, (there is also a next day button, but that will be pretty simple when I get this one working), it will update the sheetNum variable so that it can keep track and the previous button can keep being pressed...
Any ideas?

You could just parse the Name of he active sheet, subtract one from the day number and activate the previous sheet.
Sub ButtonCode()
dy = CLng(Split(ActiveSheet.Name, " ")(1))
dy = dy - 1
If dy = 0 Then Exit Sub
Sheets("Day " & dy).Activate
End Sub
So if the name of the active sheet is Day 4, then sheet Day 3 would be activated.

Related

Hiding DialogSheets [VBA]

I have problem with hide my custom dialog frame. After pressing buttons (they have calls to other macros), I still have my dialog frame, how to hide it?
I am working in "Dane_Makro" sheet.
My previous version worked fine (i did not add 2 additional buttons, but i edited vbYesNo buttons - the scheme was very similar)
Regards
Source of dialogsheets
'Public btnDlg As DialogSheet
Sub CallBots()
Dim btnDlg As DialogSheet
Dim ButtonDialog As String
ButtonDialog = "CustomButtons"
Dim klik As Boolean
klik = True
Dim oSHL As Object: Set oSHL = CreateObject("WScript.Shell")
Application.ScreenUpdating = False
Application.EnableEvents = False
On Error Resume Next
Application.DisplayAlerts = False
ActiveWorkbook.DialogSheets(ButtonDialog).Delete
Err.Clear
Application.DisplayAlerts = True
Set btnDlg = ActiveWorkbook.DialogSheets.Add
With btnDlg
.Name = ButtonDialog
.Visible = xlSheetHidden
With .DialogFrame
.Height = 70
.Width = 300
.Caption = "Generowanie plików do BOTÓW"
End With
.Buttons("Button 2").Visible = False
.Buttons("Button 3").Visible = False
.Labels.Add 100, 50, 100, 100
.Labels(1).Caption = "Jak utowrzyć pliki wsadowe do botów?"
.Buttons.Add 220, 44, 130, 18 'Custom Button #1,index #3
With .Buttons(3)
.Caption = "Nowe pliki wsadowe"
.OnAction = "MakeBotsNew"
End With
.Buttons.Add 220, 64, 130, 18 'Custom Button #2,index #4
With .Buttons(4)
.Caption = "Konsolidacja plików wsadowych"
.OnAction = "MakeBotsConso"
End With
If .Show = False Then
oSHL.PopUP "Anulowanie procesu", 1, "Tworzenie plików", vbInformation
klik = False
End If
End With
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'On Error Resume Next
DialogSheets("CustomButtons").Delete
Err.Clear
Application.DisplayAlerts = True
Application.ScreenUpdating = True
btnDlg.Visible = xlSheetVeryHidden
'Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Answer Updated:
You're going to need to add an (optional?) argument to your MakeBotsNew and MakeBotsConso macros, like so:
Sub MakeBotsNew(Optional Name As String = "")
'Existing Code here
'After existing code:
If Len(Name) > 0 Then ThisWorkbook.DialogSheets(Name).Hide 'Hide dialog box
End Sub
Then, you need to add the ButtonDialog name as an argument to the .OnAction, which also means wrapping it it single-quotes:
.OnAction = "'MakeBotsNew """ & ButtonDialog & """'"
(I still don't understand A) why you are creating your Dialog in code instead of doing it beforehand and B) why you are using a DialogSheet instead of a UserForm)
Old Answer:
As a DialogSheet is a Sheet, you need to set the .Visible property to xlSheetHidden or xlSheetVeryHidden
Using .Hide is for UserForms, which replaced DialogSheets back in... 2000?

Userform stops other sheets from scrolling

I have a few userforms. One is a popup that shows instructions and another is for entering quantities. Problem is when I click one and close it (each closes with Unload Me) then when I switch sheets with a sht.Activate macro button that sheet won't scroll. Looks like the sheet is frozen. I can fix the problem by loading the userform and closing it again on the current sheet to "Unfreeze" the sheet.
Any idea why this is happening?
UserForm
Private Sub UserForm_Click()
Unload Me
End Sub
Below is how I call it from a button.
Sub Instructions()
With UserFormInstructions
.StartUpPosition = 0
.Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
.Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
.Show
End With
End Sub
Sheet Button
Sub goto630()
Application.ScreenUpdating = False
Dim sht2 As Worksheet
Set sht2 = ThisWorkbook.Worksheets("Foundation Plates")
Dim sht3 As Worksheet
Set sht3 = ThisWorkbook.Worksheets("630 BOM")
sht3.Activate
sht3.Unprotect
sht2.Visible = True
sht3.Visible = True
On Error GoTo 0
ActiveWindow.Zoom = 90
ActiveWindow.DisplayHeadings = True
ActiveWindow.DisplayHorizontalScrollBar = True
ActiveWindow.DisplayVerticalScrollBar = True
Application.DisplayFormulaBar = True
sht3.DisplayPageBreaks = False
sht2.Protect
sht3.Protect _
DrawingObjects:=False, _
Contents:=True, _
Scenarios:=False, _
UserInterFaceOnly:=False, _
AllowFormattingCells:=True
Call NoSelect
Set sht3 = Nothing
Application.ScreenUpdating = True
End Sub
Sub NoSelect()
Application.ScreenUpdating = False
Range("D1").Select
ActiveWindow.SmallScroll ToLeft:=4
Application.ScreenUpdating = True
End Sub
Thanks

Paste data from another worksheet into next row in a loop

I need to open a dialog box and select a workbook. Then copy the data placed in that workbook (which has only 1 sheet with same name all the time).
I want to do the process for many workbooks by using a loop for vbyesno.
This is the only part which is not working because I want to paste data under Range("a14"), then loop and then paste under the data pasted in a14.
Below is the macro which is being called from another macro.
Sub prompt()
Application.DisplayAlerts = False
Dim Target_Workbook As Workbook
Dim Source_Workbook As Workbook
Dim Target_Path As Range
d = MsgBox("Add record?", vbYesNoCancel + vbInformation)
If d = vbNo Then
ActiveSheet.Range("a13").value = "No data Found"
ActiveSheet.Range("a13").Font.Bold = True
ThisWorkbook.Save
ElseIf d = vbCancel Then
Sheets("MPSA").Delete
ThisWorkbook.Save
ElseIf d = vbYes Then
Sheets("MPSA").Range("a14").value = "NAME"
Sheets("MPSA").Range("b14").value = "NUMBER"
Sheets("MPSA").Range("c14").value = "AGR NUMBER"
Sheets("MPSA").Range("d14").value = "ENTITY NAME"
Sheets("MPSA").Range("e14").value = "GROUP"
Sheets("MPSA").Range("f14").value = "DELIVERABLE"
Sheets("MPSA").Range("g14").value = "DELIVERAB"
Sheets("MPSA").Range("h14").value = "IS COMPON"
Sheets("MPSA").Range("i14").value = "PACKAGE"
Sheets("MPSA").Range("j14").value = "ORDERS"
Sheets("MPSA").Range("k14").value = "LICNTITY"
Sheets("MPSA").Range("l14").value = "QUANTITY"
Sheets("MPSA").Range("m14").value = "ORDERANUMBER"
Sheets("MPSA").Range("n14").value = "ORDERAM NAME"
Sheets("MPSA").Range("o14").value = "PAC NUMBER"
Sheets("MPSA").Range("p14").value = "PACKAGAME"
Sheets("MPSA").Range("q14").value = "ITTION"
Sheets("MPSA").Range("r14").value = "LICENSE TYPE"
Sheets("MPSA").Range("s14").value = "ITEM VERSION"
Sheets("MPSA").Range("t14").value = "REAGE"
Sheets("MPSA").Range("u14").value = "CLIIT"
Sheets("MPSA").Range("v14").value = "LICEAME"
Sheets("MPSA").Range("w14").value = "ASSATE"
Sheets("MPSA").Range("x14").value = "ASSTE"
Sheets("MPSA").Range("y14").value = "ENTITTUS"
Sheets("MPSA").Range("z14").value = "ASSGORY"
Sheets("MPSA").Range("aa14").value = "PURCHAYPE"
Sheets("MPSA").Range("ab14").value = "BILLTHOD"
Sheets("MPSA").Range("ac14").value = "SALETER"
Cells.Columns.AutoFit
Target_Path = Application.GetOpenFilename
Set Target_Workbook = Workbooks.Open(Target_Path)
Set Source_Workbook = ThisWorkbook
Target_Data = Target_Workbook.Sheets(1).Range("A1").CurrentRegion.Copy
Target_Workbook.Close
Source_Workbook.Sheets("MPSA").Range("a14").End(xlDown).Offset(1, 0).PasteSpecial = Target_Data
ActiveCell.EntireRow.Delete
ThisWorkbook.Save
ThisWorkbook.Save
End If
End Sub
I was going to propose a mechanism to achieve the loop, supposing that your current code is somewhere near what you want to achieve. But I found many mistakes so I had to refactor it, hopefully it will get you a step further.
The following code will continue looping until user presses Cancel in the file dialog box:
Sub prompt()
Dim d As VbMsgBoxResult: d = MsgBox("Add record?", vbYesNoCancel + vbInformation)
If d = vbNo Then
Sheets("MPSA").Range("a13").value = "No data Found"
Sheets("MPSA").Range("a13").Font.Bold = True
ThisWorkbook.Save
Exit Sub
End If
If d = vbCancel Then
Sheets("MPSA").Delete
ThisWorkbook.Save
Exit Sub
End If
On Error GoTo Cleanup
Application.DisplayAlerts = False: Application.EnableEvents = False: Application.ScreenUpdating = False
Sheets("MPSA").Range("a14:ac14").value = Array( _
"NAME", "NUMBER", "AGR NUMBER", "ENTITY NAME", "GROUP", "DELIVERABLE", "DELIVERAB", "IS COMPON", _
"PACKAGE", "ORDERS", "LICNTITY", "QUANTITY", "ORDERANUMBER", "ORDERAM NAME", "PAC NUMBER", "PACKAGAME", _
"ITTION", "LICENSE TYPE", "ITEM VERSION", "REAGE", "CLIIT", "LICEAME", "ASSATE", "ASSTE", _
"ENTITTUS", "ASSGORY", "PURCHAYPE", "BILLTHOD", "SALETER")
Sheets("MPSA").Columns.AutoFit
Dim Target_Path: Target_Path = Application.GetOpenFilename
Do While Target_Path <> False ' <-- loop until user cancels
Dim Target_Workbook As Workbook: Set Target_Workbook = Workbooks.Open(Target_Path)
Target_Workbook.Sheets(1).Range("A1").CurrentRegion.Copy _
ThisWorkbook.Sheets("MPSA").Range("a1000000").End(xlUp).Offset(1)
Target_Workbook.Close False
ActiveCell.EntireRow.Delete
ThisWorkbook.Save
Target_Path = Application.GetOpenFilename
Loop
Cleanup:
If Err.Number <> 0 Then MsgBox "Something went wrong: " & vbCrLf & Err.Description
Application.DisplayAlerts = True: Application.EnableEvents = True: Application.ScreenUpdating = True
End Sub

Generating dynamic charts with VBA

I have to create almost 200 charts of time series. So I tried to write a macro that finishes most of the work I need to do.
I generated names for the time series like this as an example:
Name:= AKB_ExampleA
The name refers to a dynamic range which I declared with this formula:
=OFFSET('sheet1'!$C$7:$C$137;0;0;COUNT('sheet1'!$C$7:$C$206))
So now to the macro I coded so far:
Sub graphik_erstellen()
Call graphik1("AKB")
End Sub
Sub graphik(Name As String)
'
Dim Ch As Chart
Dim RngToCover As Range
Set Ch = charts.Add
Set Ch = Ch.Location(Where:=xlLocationAsObject, Name:="Charts")
With Ch
.ChartType = xlLine
.SetSourceData Source:=Range(Name & "_ExampleA")
.SeriesCollection(1).XValues = Range("Datum_Volumen")
.SeriesCollection(1).Name = "SERIES1"
.FullSeriesCollection(1).Select
With Selection.Format.Line
.Visible = msoTrue
.ForeColor.RGB = RGB(192, 0, 0)
.Transparency = 0
End With
.HasTitle = True
.ChartTitle.Text = Name & ", Volumen (nach Korrektur)"
.HasLegend = True
.Legend.Position = xlLegendPositionBottom
.Legend.Select
Selection.Format.TextFrame2.TextRange.Font.Size = 11
Selection.Format.TextFrame2.TextRange.Font.Bold = msoTrue
With .Parent
.top = 100
.left = 100
.height = 287.149606299
.width = 543.685039370078
.Name = Name & "_chart"
End With
End With
End Sub
My problem is, that if I do that, the dynamic range is not really considered. It takes the range of the name (which is $C$7:$C$137) but it should refer to the name itself (in order to be dynamic).
So if I click on the chart to see the series, the series values are declared as: ='sheet1'!$C$7:$C$137 instead of ='sheet1'!ExampleA.
I would be really, really grateful if somebody could help me out.
Best
Elio
I have rearranged a few lines of code and tried to place comments refering to them as well.
Let me know what works. Youjust might need to change SeriesCollection to FullSeriesCollection. Other than that the code works in my Excel 2010.
The first Sub I just get the Range size according to the data available in Column "C" from Row 7.
Let me know.
Option Explicit
Sub graphik_erstellen()
'You always want to use direct reference to a sheet/range chart
'Refering to the WorkBook they are in and the worksheet as well.
'especially if you are opening multiple WorkBooks / Sheets
Dim CurrentWorkSheet As Worksheet
Set CurrentWorkSheet = Workbooks("Book1").Worksheets("Sheet1")
'Dynamically finding the end of the data in Column C
Dim LastRow As Long
LastRow = CurrentWorkSheet.Cells(CurrentWorkSheet.Rows.Count, "C").End(xlUp).Row
'Setting the range using the document reference aswell
Dim AKB As Range
Set AKB = Workbooks("Book1").Worksheets("Sheet1").Range(Cells(7, "C"), Cells(LastRow, "C"))
Call graphik(AKB)
End Sub
Sub graphik(Name As Range)
Dim DataChart As Chart
Dim RngToCover As Range
Set DataChart = Workbooks("Book1").Charts.Add
'With Excel 2010 the line above will automatically add the chart as a sheet and not aobject in a sheet
'Set DataChart = DataChart.Location(Where:=xlLocationAsObject, Name:="Charts")
With DataChart
.Name = "Charts" ' This will be the Name of the CHart Tab
.ChartType = xlLine
.SetSourceData Source:=Name
'You can see below I avoided the Select and Selection
With .SeriesCollection(1)
'Using Offset I just used the data one cell to the left of the range
.XValues = Name.Offset(0, -1)
.Name = "SERIES1"
With .Format.Line
.Visible = msoTrue
.ForeColor.RGB = RGB(192, 0, 0)
.Transparency = 0
End With
End With
.HasTitle = True
.ChartTitle.Text = "MIDDEL TOP TEXT" 'Name & ", Volumen (nach Korrektur)"
.HasLegend = True
With .Legend
.Position = xlLegendPositionBottom
.Format.TextFrame2.TextRange.Font.Size = 11
.Format.TextFrame2.TextRange.Font.Bold = msoTrue
End With
'Not sure about this, it doesnt work in my Excel 2010
'
With .Parent
.Top = 100
.Left = 100
.Height = 287.149606299
.Width = 543.685039370078
.Name = Name & "_chart"
End With
End With
End Sub
Let me know what your intention is for the Sheet and Chart names and then I can help with getting that to what you need as well.

How to lock excel aspect/visual options

I am trying to lock the aspect/visual options of an excel file, so when other people open it, it remains as I set and cannot change it.
When I set the aspect options and other people open it in their PCs, all settings are gone.
I would like to set the aspect as the following:
Do not show formula bar
Do not show headings
Minimize the Ribbon
Additionally I would like to lock specific settings for each sheet:
Zoom:
100% for sheet 1 and 4
90% for sheet 2 and 3
Freeze panes:
Unfreeze for sheet 1 and 4
Freeze the first 3 columns for sheet 2 and 3
Is there anyway of doing this?
Thanks!
I used this in the 'thisworkbook' excel object. The send keys worked but i would be careful as these are prone to errors.
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If ActiveSheet.Name = "Sheet1" Or ActiveSheet.Name = "Sheet4" Then
ActiveWindow.FreezePanes = False
ActiveWindow.Zoom = 90
ElseIf ActiveSheet.Name = "Sheet2" Or ActiveSheet.Name = "Sheet3" Then
Columns("d:d").Select
ActiveWindow.FreezePanes = True
ActiveWindow.Zoom = 90
End If
Application.DisplayFormulaBar = False
ActiveWindow.DisplayHeadings = False
If Application.CommandBars("Ribbon").Height >= 150 Then
SendKeys "^{F1}"
End If
End Sub
Hopefully this will work, if not let me know!
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If ActiveSheet.Name = "Sheet1" Or ActiveSheet.Name = "Sheet4" Then
ActiveWindow.FreezePanes = False
ActiveWindow.Zoom = 90
ElseIf ActiveSheet.Name = "Sheet2" Or ActiveSheet.Name = "Sheet3" Then
Columns("d:d").Select
ActiveWindow.FreezePanes = True
ActiveWindow.Zoom = 90
End If
Application.DisplayFormulaBar = False
ActiveWindow.DisplayHeadings = False
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",False)"
ActiveWindow.ScrollRow = 1
ActiveWindow.ScrollColumn = 1
End Sub