I am trying to create a VBA that will set the calculation of a specific column/range of columns to manual, within a table that is set to calculate automatically.
Because the dashboard is already so slow I do not want these specific columns/range to calculate automatically like the rest of the table.
I'm using this vba but my whole table is still calculating automatically when I first load my cust # into my excel dashboard.
Sub Recalc()
Selection.Calculate
End Sub
Any ideas?
You cannot directly turn calculations on or off to a specific section, it has to apply to the application. Your best bet would be to turn all calculations off for the application, but then set a change macro to recalculate when changeshappen with a specific range. This would need to be written in the appropriate SHEET section of a your VBA editor, not MODULE
Example:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B3:Z100")) Is Nothing Then
Range("B3:Z100").Calculate
End If
End Sub
Related
Currently I'm creating a macro that reads data from a table column, Asset No. The data is obtained through drop-down menu via data validation from another table in another sheet, DieMaster.
It will then perform Index and Match to find the matching data from DieMaster and insert it into Description column.
In addition, Upon obtaining data, the table column will then copy and paste as value to get the data only. That way the formula won't slow down filter searches.
This is what I have come up with.
Sub convert()
Dim osh As Worksheet
Set osh = ActiveSheet
osh.Range("ProjectEntry[Description]").Formula = "=IF(ISNA(INDEX(DieMaster,MATCH(B4,DieMaster[Asset No],FALSE),2)),"""",INDEX(DieMaster,MATCH(B4,DieMaster[Asset No],FALSE),2))"
osh.Range("ProjectEntry[Description]").Copy
osh.Range("ProjectEntry[Description]").PasteSpecial xlPasteValues
End Sub
I have tested the macro and it works perfectly. However the issue I have now is trying to assign the macro to Asset No column. My plan is to have it so that when a value is selected in a cell within the Asset No column via aforementioned drop-down menu, it will automatically show me the data for description.
Since I cannot assign macro to column using the traditional method, is there an alternative?
You can use the Worksheet_Change Event to accomplish this:
Private Sub Worksheet_Change(Target as Range)
If Not Intersect(Target, Me.ListObjects("ProjectEntry").ListColumns("AssetNo").DataBodyRange) Is Nothing Then
With Me.Range("ProjectEntry[Description]")
.Formula = "=IF(ISNA(INDEX(DieMaster,MATCH(B4,DieMaster[Asset No],FALSE),2)),"""",INDEX(DieMaster,MATCH(B4,DieMaster[Asset No],FALSE),2))"
.Value = .Value
End With
End If
End Sub
My syntax may be slightly off (since I am not on my normal computer), but it will get you close enough to tweak on your own.
I've searched online and couldn't find a code to do what I'm looking to do and I hit a tumbling block..
We're currently looking to implement a CRM-like reporting system for our reps in excel. Our reps would fill out customer data in a row and just update the relevant cells when the account status changes one way or another.
The report is all built and works but we're lacking the account history part so what we're looking to do, is to copy the whole row in a new row to a different sheet or workbook any time the data in column I is updated for a row so there's a history of all relevant changes kept automatically on a separate sheet or worksheet.
I've searched and looked online at different codes and the tracking changes option but could not find a code that would automatically copy only the whole relevant row on update and we really need the whole row to be copied for the data to remain meaningful to us so track changes doesn't work for our needs. We'd also require for these steps to happen without action from our users.
Any help on how this could be accomplished would be greatly appreciated.
Use the WorksheetChangeEvent to detect when something has been changed:
Private Sub Worksheet_Change(ByVal Target As Range)
' do stuff
End Sub
Put the above code into the worksheet object (double click on the worksheet in the code editor).
Use Application.Intersect to narrow down what has been changed. For instance if you're only interested in cells I1 to I10000:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Target, Range("I1:I1000")) Is Nothing Then
' do stuff
End If
End Sub
Then copy the required row:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Target, Range("I1:I10000")) Is Nothing Then
Rows(Target.Row).copy
' paste it where you want it
End If
End Sub
Target is the range for the affected cell. Of course the user can affect more than one cell at once e.g. by autofilling, so you may need to put some additional logic e.g if Target.Rows.Count > 1, but you get the idea.
I am currently trying to obtain historical information about how the backlog is developing.
My Excel file is based on queries from an Access Database which can give me a view of the current situation.
I would like to automatically run a macro every time the week number changes. I am currently using the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("D3")) Is Nothing Then
Call KPIupdate
End If
End Sub
The macro that should fire is called KPIupdate
My problem is that the Macro only fires if I click the cell. I would like it to just fire when the number changes. The cell "D3" is linked to another cell with the formula =Weeknum(Today();21)
I hope you can help me
According to the MSDN entry for Worksheet_Change:
This event does not occur when cells change during a recalculation. Use the Calculate event to trap a sheet recalculation.
To use Worksheet_Calculate to trap the change in a cell that is set by a formula looking at another cell, you need to set a variable to hold the value of the 'Target' and then check if it has changed after the Calculate event fires.
Here is a simple example:
Option Explicit
Private strCurrentWeek As String
Private Sub Worksheet_Calculate()
If Me.Range("A1").Value <> strCurrentWeek Then
'the linked cell changed
Debug.Print "Sheet1!A1 was changed"
'call another macro
End If
'update the new current week
strCurrentWeek = Me.Range("A1").Value
End Sub
To test this, just set the formula in A1 to be =B1 and then change the value of B1 and check the output in the Immediate window.
You can adapt this code to call KPIupdate where my Debug.Print... statement is.
When you have a data table in Excel, part of the standard functionality is that pressing tab in the last cell adds a new row at the bottom of the table. I want to auto-populate that new row with useful default values. In particular I want to put current date-time in one cell, and copy values into some other cells from the previous row of the table.
It is not workable to do that using formulae -- e.g. using =now() for the date-time stamp is inadequate because it will be auto-updated every time the spreadsheet recalculates, whereas I want it to retain the date-time at the moment when the row was added.
So I am trying to write VBA to be triggered by the event of the row being added, and in that code to write values into the cells of the new row. From MS documentation I thought DataTable.TableNewRow would be the appropriate event. But when I try to write any code for that event it is not being executed. When I look up DataTable in the VBA object browser the TableNewRow event is not listed.
Versions:
VBA for Applications 7.1
Excel 2013
So my questions:
Is the direction of my thinking right, or can you suggest a better approach?
Can you offer any working code that does something like this?
Is DataTable.TableNewRow the event I should be working with?
What do I need to do to get that event accessible in my VBA code?
You can try this:
Write this code in Thisworkbook.
Private Sub Workbook_Open()
Set ref_tbl = Sheet1.ListObjects(1).DataBodyRange
End Sub
Then below code in a Worsksheet Object.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo halt
Application.EnableEvents = False
Dim tbl_rng As Range
Set tbl_rng = Me.ListObjects(1).DataBodyRange
If Not Intersect(Target, tbl_rng) Is Nothing Then
If tbl_rng.Rows.Count > ref_tbl.Rows.Count Then
MsgBox "Table increase in size"
'~~> Do your stuff here
Set ref_tbl = tbl_rng
End If
End If
forward:
Application.EnableEvents = True
Exit Sub
halt:
MsgBox Err.Number & ": " & Err.Description
Resume forward
End Sub
You will also need a Module to declare the public variable
Public ref_tbl As Range
So basically, this will tell you when your table increase in size.
If we're able to capture that, then you can do your stuff when that condition is met.
This works in the situation you describe in your question.
It will not work though when you insert row between entries in the table. Anyways, HTH.
I am trying to automate the updating of a status date in an Excel Worksheet based on if any changes have taken place within certain cells. In my example, I want the date in cell "S6" to equal today's date is any of the data in cells "B6:L34" have been changed/ deleted/ info added. I am not sure what VBA code to use or how. Any clues? This would be for only changes within those cells on that worksheet; not changes throughout the Workbook. Thank you.
I would look into workbook/worksheet events throughout the internet. You can create private sub functions that automatically runs whenever a change is made. It sounds like you need a private sub worksheet_selection or worksheet_change event handler. Look up something simple like "workbook_open VBA excel" and you can get A great feeler for how event handlers work.
Then I suggest you to research the INTERSECT function and play around with it. It allows you to declare a TARGET variable and range for you to manipulate, basically saying that if anything happens to that range, this is how I want to manipulate the TARGET. The TARGET is basically the cell that was being manipulated within the range.
There might be other factors - but this will start you off very quickly
This code will update the cell S6 with today's date when anything inside the range B6:L34 has been edited.
Private Sub Worksheet_Change(ByVal Target As range)
If Not Intersect(Target, Target.Worksheet.range("B6:L34")) Is Nothing Then
Sheets("Sheet1").Range("S6") = Date
End If
End Sub
EDIT:
For this to work, make sure this code is placed within the sheet that you're using (see below):