1

I am a new to VBA. I will have many sheets in a workbook, for 300+ projects, and I wish to create a macro that is run when a project sheet is opened.
Each sheet in Row 4 has the months from 2017 to 2031 (day 1 of the month is used) with 1 Jan 17 being in H4. Columns A to F are frozen. On opening sheet I want the present month column selected (in say Row 19) so that, as seen on the screen, I see columns A to F then last month, then today's month followed by later months. May 25 is column DD so the aim would be to see columns A to F and DB to DG Each of these project sheets are frozen on G5, both above and to the left

I have been trying to do this, and failing!

Sub Macro3()
'   Macro3 Move to Current Month column
    Range("G6").Select      
'   To ensure that Column G is visible next to Column F

    Cells(19, 110).Select   
'   For the columns To go Right so that the current month column can be seen (and, say, those of the 2 months before and 6 after - this does depend how wide the Excel window is.)   
End Sub

This does work but the column number (110), which is Column DF, is hardcoded. I want it to automatically change as the months pass.

In another sheet in this workbook I have a way of generating this I have named this cell Screen_Column.

I have failed to find a way to introduce the value in Screen_Column into Cells(19, 110).Select

  • with the 110 changing to 11? at the end of every month

I thought to do this

    Dim COLU As Integer
    Screen_Column = COLU
    Range("G6").Select
    Cells(19, COLU).Select

This did not work. Cannot get the value of Screen_Column to work in the Cells line

I am sure I have made a basic error and I know I may have missed a simple way of doing this but I have spent some time failing to find an answer.

I will be grateful for help and guidance. Thanks

2
  • Please explain how to identify the correct sheets. Do they all start with Project, are they all sheets except a list, e.g., [Sheet1,Sheet2], or something else? What exactly do you want to show and select for the current month? Is it columns A:H,DB... and rows 1:4,19... (or all rows) and select DD19? Commented May 4 at 5:14
  • All the project sheets begin with their (unique) reference number - Two letters but the first one is always A, followed by a 4 digit number (but may become a 5 digit number in a year or so as in the 8000s at moment) and some have up to 3 characters suffixed. To show: Columns - basically A to F (screen already frozen upto Column F) then depending on the width of the viewers screen, say 8 columns in addition to the frozen left margin with the left most column showing being 2 months before the current month. Rows - Frozen down to Line 4, working area goes another 50 rows down so no worry Commented May 5 at 15:13

3 Answers 3

1

Try this.

Dim COLU As Integer   
COLU = 110   
Range("G6").Select   
Cells(19, COLU).Select
Sign up to request clarification or add additional context in comments.

1 Comment

Danny, thanks for this - this looks nicely simple for the nube I am but although there are flashy ways to get the column integer in other answers I feel that at this stage something simpler is easier to adapt. I have the column number worked out and saved on another sheet in a cell named Screen_Column. In the second line of your code I would like to say COLU = Screen_Column (This may be the wrong syntax etc. I tried and got Error 1004) My plan, when the sub routine works, is to have it triggered “Workbook_Open” event affecting all project sheets
0

A Workbook SheetActivate: Scroll and Select

ThisWorkbook Module

Private Sub Workbook_SheetActivate(ByVal sh As Object)
    ScrollSelectProject sh
End Sub

Standard Module, e.g. Module1, or ThisWorkbook Module

Sub ScrollSelectProject(ByVal sh As Object)
    
    ' Define constants.
    Dim SHEET_EXCEPTIONS() As Variant: SHEET_EXCEPTIONS = Array( _
        "Sheet2", "Sheet3")
    Const FIRST_DATE_CELL_ADDRESS As String = "H4"
    Const SELECT_ROW As Long = 19
    Const PREVIOUS_MONTHS As Long = 2
    Const SCROLL_TO_ROW As Boolean = False
    
    ' Exclude sheets from the list.
    If IsNumeric(Application.Match(sh.Name, SHEET_EXCEPTIONS, 0)) Then Exit Sub
    
    ' Calculate the 'Select' column.
    Dim SelectColumn As Long:
    With sh.Range(FIRST_DATE_CELL_ADDRESS)
        Dim FirstDate As Date: FirstDate = .Value
        Dim Today1st As Date: Today1st = DateSerial(Year(Date), Month(Date), 1)
        SelectColumn = DateDiff("m", FirstDate, Today1st) - .Column + 1
    End With
    
    ' Calulate the 'Scroll' row and column.
    Dim ScrollRow As Long:
    If SCROLL_TO_ROW Then
        ScrollRow = SELECT_ROW
    Else
        ScrollRow = ActiveWindow.SplitRow + 1
    End If
    Dim ScrollColumn As Long: ScrollColumn = SelectColumn - PREVIOUS_MONTHS
    
    ' Scroll.
    Application.Goto sh.Cells(ScrollRow, ScrollColumn), True
    
    ' Select.
    Application.Goto sh.Cells(SELECT_ROW, SelectColumn)
    
    ' Redraw selection (prevent 'previous selection' also remain visible).
    Application.ScreenUpdating = True
    
End Sub

Comments

0

You want to investigate the worksheet events - in particular WorksheetActivate. You can do this within each sheet. For the purposes of this answer, I will assume that the event handler will call a custom macro.

Public Sub SelectDatedColumns(ws as Worksheet)
    Dim SelectedColumn as Long ' Note: Long, not Integer
    'Assumption: eighth column ('H') represents January 2017
    Dim TodaysDate as Date ' for convenience, to avoid multiple calls to Now()
    TodaysDate = Now()
    SelectedColumn = (Year(TodaysDate) - 2017) * 12 + Month(TodaysDate) + 8 
    ' Note the three magic numbers in the previous statement.
    ws.Columns(SelectedColumn).Select
End Sub

Not tested.

Better coding practice would be to set this as a Function and return a range (ws.Columns(SelectedColumn)) so that the calling routine can decide if to select/display it - and prevent a future race condition where multiple routines are trying to display cells.

Edit: Ran a test based on a comment from OP. The only change to the routine was to parameterise two magic numbers in the code above. The code ran.

Insert the following code into ThisWorkbook module.

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim isProjectSheet As Boolean
' TODO: Code here to validate that it is a project sheet that has been selected. For this example, let us assume it is true.
' TODO: Extend this code to allow for other 'activate' automation.

    isProjectSheet = True ' place holder for the results of validation.
    If isProjectSheet Then
        Dim baseYear As Long
        Dim columnOffset As Long
        baseYear = 2024 '2017
        columnOffset = 8     'Assumption: eighth column ('H') represents January 2017
        SelectDatedColumns Sh, baseYear, columnOffset 'expect 12*1 + 5 + 8 = 25 - "Y"
    End If


End Sub


Private Sub SelectDatedColumns(ws As Worksheet, baseYr As Long, colOffset As Long)
    Dim SelectedColumn As Long ' Note: Long, not Integer
    Dim TodaysDate As Date ' for convenience, to avoid multiple calls to Now()
    TodaysDate = Now()
    SelectedColumn = (Year(TodaysDate) - baseYr) * 12 + Month(TodaysDate) + colOffset
    ' Note the single magic number in the previous statement.
    ws.Columns(SelectedColumn).Select
End Sub

2 Comments

AJ – Thank you for this but despite my comment the reply above I think I can understand what you have done but when I added it as a sub, it ran until ‘ws.Columns(SelectedColumn).Select’ where a 424 runtime error– Object required appeared. You said ‘Not tested’ – would it be possible for you to test the code?
@Madcap I tested the code and it ran for me (see edits). Based on your description, I can only guess that you tried to run the routine without assigning a worksheet (ws) first. In my edit I use the worksheet identified in the event handler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.