Move cell with sum function down as new entries occur using row.count - excel

I'm a bit surprised this has proven to be such a challenge. On sheet 1 I have the input which looks as follows:
Private Sub CommandButton1_Click()
erw = Sheet2.Cells(1, 1).CurrentRegion.Rows.Count + 1
'erw.Offset(1).EntireRow.Insert Shift:=xlDow
If Len(Range("c3")) <> 0 Then
Sheet2.Cells(erw, 1) = Range("c3")
Sheet2.Cells(erw, 2) = Range("c4")
Sheet2.Cells(erw, 3) = Range("c5")
Range("c3") = ""
Range("c4") = ""
Range("c5") = ""
Else
MsgBox "You must enter an amount"
End If
End Sub
No issues with the above, where I'm running into a problems is with the following on sheet 2 where the information is stored:
Sub AddUp()
Dim rngcount As Long
Dim TotalA As Long
Dim rng2 As Range
rngcount = Cells(Rows.Count, "A").End(xlUp).Row
Set rng2 = Range("A28")
TotalA = Application.WorksheetFunction.Sum(ThisWorkbook.Sheets("sheet2").Range("a1:a" & rngcount))
rng2 = TotalA
The real issue is the following Set rng2 = Range("A28") as this is essentially a cheat I've been using. I know that there will not be more than 26 entries to be summed and then a new sheet will be started. I currently have the TotalA amount Set to be put in A28, but what I am trying to do is have the TotalA cell move down as more entries are put in. Put another way I would rather the range where TotalA will be able to move as more entries are put in.
I began with the following erw.Offset(1).EntireRow.Insert Shift:=xlDowbut I moved away from that as the insertion of a row needs to occur on sheet2I've left it here for this posting in case there is any valuable feed back.
What I've been focusing on instead is trying to use CurrentRegion.offset(1) to keep moving the cell that holds the sum function down. Problem is I cannot figure out how to declare a range based on rngcount This may be the problem because perhaps I should not be using rngcount as it is not an object, but my thinking is/was that I could turn that rngcount into an object and then use CurrentRegion.offset(1) A bit long winded, hope the goal comes through clearly. Thanks

Take a look at this and see if it does what you want.
Sub AddUp()
Dim rngcount As Long
Dim TotalA As Long
Dim rng2 As Range
rngcount = Cells(Rows.Count, "A").End(xlUp).Row
Set rng2 = Cells(rngcount + 1, 1)
TotalA = Application.WorksheetFunction.Sum(ThisWorkbook.Sheets("sheet2").Range("a1:a" & rngcount))
rng2 = TotalA
End Sub

I usually like to put total formulas in the worksheet instead of doing the math in the macro.
Sub AddUp()
Dim rngcount As Long
Dim TotalA As Long
Dim TotalStartRng As Range
Dim TotalEndRng As Range
rngcount = Cells(Rows.Count, "A").End(xlUp).Row
Set TotalStartRng = Cells(1, 1)
Set TotalEndRng = Cells(rngcount, 1)
Cells(rngcount + 1, 1) = "=SUM(" & TotalStartRng.Address & ":" & TotalEndRng.Address & ")"
End Sub

Related

SpecialCells Type Visible cannot find last row in vba

All, I am working part of my code where I want to update filtered noncontiguous cells with index / match. Core of my code is working in proper manner in another case but here seems wrong and do not know what is the reason behind. Working turn endless and could cause that no last row find in section here: Set rngI = usedR.Resize(usedR.Rows.Count - 1).Offset(5).Columns("I:I").SpecialCells(xlCellTypeVisible). Checked with debug.print the result which shows me the end as wrong...$I$174:$I$1046999...proper has to be $I$174:$I$197...what could be the reason behind?
Another question using lastrow calculation..on this way this doesnt work, Dim lastrow As Long, lastrow = rngD(Rows.Count, 1).End(xlUp).row I have to correct like this to count...lastrow = rngD(rngD.Rows.Count, 1).End(xlUp).row. What's the reason behind that once working on first way, once only if I double type range. This code is in Personal folder if it counts anyway
Sub Macro2()
Dim wbD As Workbook: Set wbD = Workbooks("dashboard-advanced.xls")
Dim wsD As Worksheet: Set wsD = wbD.Sheets("Sheet1")
Dim rngD As Range: Set rngD = wsD.Range("A:C")
Dim wbCallLCL As Workbook: Set wbCallLCL = Workbooks("CALL_REPORT.xlsx")
Dim wsCallLCL As Worksheet: Set wsCallLCL = wbCallLCL.Sheets("LCL")
Dim rngCallLCL As Range: Set rngCallLCL = wsCallLCL.Range("A:V")
rngCallLCL.autofilter Field:=10, Criteria1:=Blanks
Dim lastrow As Long
lastrow = rngD(rngD.Rows.Count, 1).End(xlUp).row
Dim usedR As Range, rngI As Range, A As Range, C As Range
Set usedR = wsCallLCL.UsedRange
Set rngI = usedR.Resize(usedR.Rows.Count - 5).Offset(1).Columns("I:I").SpecialCells(xlCellTypeVisible)
For Each A In rngI.Areas
For Each C In A.Cells
res = Application.Match(C.Value, wsD.Range("A2:" & "A" & lastrow), 0)
If IsError(res) Then
C.Offset(, 1).Value = ""
Else
C.Offset(, 1).Value = Application.WorksheetFunction.Index(wsD.Range("B2:" & "B" & lastrow), res, 0)
End If
Next C
Next A
End Sub

Convert Excel Array formula into VBA code

I have two set of range named as LIST_KEY and LIST_CAT. In Column A, user will add some data which will contain one of the one of the text from LIST_KEY. I would like to get corresponding Category list from LIST_CAT depends upon the Key value
I am using below VBA code to achieve this. This include a Array formula.
Sub match()
Dim ss As Workbook
Dim test As Worksheet
Set ss = Excel.Workbooks("test.xlsm")
Set test = ss.Worksheets("Sheet1")
For i = 2 To test.Cells(Rows.Count, "A").End(xlUp).Row
Cells(i, "B").FormulaArray = "=INDEX(LIST_CAT,MATCH(TRUE,ISNUMBER(SEARCH(LIST_KEY,RC[-1])),0))"
Cells(i, "B").Formula = Cells(i, "B").Value
Next i
End Sub
This code works perfect if there is less data to fetch. But in my original use case, I will have around 8000 rows. Due to this large number of columns excel will go to not responding state after 2-3 minutes.
Instead of adding Array formula to column B, Is there anyway to convert that into VBA to run this faster. Sorry, I am new to this VBA stuff and dont have much experience
Try the following code, which uses arrays instead of worksheet formulas...
Option Explicit
Sub GetCategories()
Dim sourceWorkbook As Workbook
Set sourceWorkbook = Workbooks("test.xlsm")
Dim sourceWorksheet As Worksheet
Set sourceWorksheet = sourceWorkbook.Worksheets("Sheet1")
Dim lookupArray As Variant
lookupArray = sourceWorkbook.Names("LIST_KEY").RefersToRange.Value
Dim returnArray As Variant
returnArray = sourceWorkbook.Names("LIST_CAT").RefersToRange.Value
Dim tableArray As Variant
Dim lastRow As Long
With sourceWorksheet
lastRow = .Cells(.Rows.Count, "a").End(xlUp).Row
tableArray = .Range("A2:B" & lastRow).Value
End With
Dim desc As String
Dim i As Long
Dim j As Long
For i = LBound(tableArray, 1) To UBound(tableArray, 1)
desc = tableArray(i, 1)
For j = LBound(lookupArray, 1) To UBound(lookupArray, 1)
If InStr(1, desc, lookupArray(j, 1), vbTextCompare) > 0 Then
tableArray(i, 2) = returnArray(j, 1)
Exit For
End If
Next j
Next i
sourceWorksheet.Range("B2").Resize(UBound(tableArray, 1), 1).Value = Application.Index(tableArray, 0, 2)
End Sub

Find the last filled row in a filtered column without dropping the Autofilter

How do I get the position of the last non-empty cell in a filtered column without dropping the applied Autofilter? I understand it's easy to get the number of the last visible row with
Dim ws as Worksheet, rng As Range
Set rng = Range(Letter & 1 & ":" & Letter & 1) ' where Letter is the letter code of the column
GetLastVisibleRow = ws.Range(Split(ws.Cells(, rng.Column).Address, "$")(1) & ws.Rows.count).End(xlUp).row
but I need the number of the last filled row instead. At the same time, I'd like to avoid setting
ws.AutoFilterMode = False
if it's possible.
Thanks in advance.
Probably not the most efficient or fastest method, but this appears to work:
Function GetLastCellOfColumn(ColLetter As String) As Range
Dim Col As Range
Dim Rw As Long
Set Col = Range(ColLetter & ":" & ColLetter)
Set GetLastCellOfColumn = Intersect(ActiveSheet.UsedRange, Col)
For Rw = GetLastCellOfColumn.Cells.Count To 1 Step -1
If Len(GetLastCellOfColumn.Cells(Rw).Value) > 0 Then
Set GetLastCellOfColumn = GetLastCellOfColumn.Cells(Rw)
Exit Function
End If
Next
End Function
A charming solution by #jkpieterse plus a useful comment by #BigBen is exactly what I was looking for. Just to finalize the thread, the function returning the row number is
Function GetLastFilledCellOfColumn(ws As Worksheet, ColLetter As String) As Long
Dim Col As Range, Urng As Range, Rw As Long
Set Col = ws.Range(ColLetter & ":" & ColLetter)
Set Urng = Intersect(ws.UsedRange, Col)
For Rw = Urng.Cells.count To 1 Step -1
If Not IsEmpty(Urng.Cells(Rw)) Then
GetLastFilledCellOfColumn = Rw
Exit Function
End If
Next
End Function
Problem solved.
So maybe this is an alternative way to look into:
Sub Test()
Dim rng As Range
Dim col As Long: col = 2 'Change to whichever column you interested in
Dim rw as Long
With Sheet1 'Change to whichever sheets CodeName you need
Set rng = .Range("_FilterDatabase").Columns(col)
rw = .Evaluate("MAX(IF(" & rng.Address & "<>"""",ROW(" & rng.Address & ")))")
End With
End Sub
I'm afraid I rushed this a little and might have made a mistake but will have to get going. Hopefully you understand whats going on =)
Edit:
The above would definately work, but as figured out through the chat, there is actually a ListObject involved, called Table1, which throws of the AutoFilter range. So here are two alternative ways of doing the same thing:
Sub Test()
Dim rng As Range
Dim col As Long: col = 2 'Change to whichever column you interested in
Dim rw as Long
With Sheet1 'Change to whichever sheets CodeName you need
Set rng = .Range("Table1")
rw = .Evaluate("MAX(IF(" & rng.Address & "<>"""",ROW(" & rng.Address & ")))")
End With
End Sub
Or, when you don't know the name of the table:
Sub Test()
Dim rng As Range
Dim col As Long: col = 2 'Change to whichever column you interested in
Dim rw as Long
With Sheet1 'Change to whichever sheets CodeName you need
Set rng = .ListObjects(1).Range
rw = .Evaluate("MAX(IF(" & rng.Address & "<>"""",ROW(" & rng.Address & ")))")
End With
End Sub

Is it possible to lookup for a value from another sheet in the same workbook?

I have a workbook with multiple spreadsheets. One of the sheets is called "Master Filtered" and the other is called "MTL OR TOR"
I want to fill in the column K of the "Master filtered" sheet with a lookup value from the "MTL or TOR" sheet in the second column. I wrote this piece of code but it is not working.
Sub MTL_OR_TOR()
Dim AcctNb As String
Dim result As String
Worksheets("Master Filtered").Activate
Dim lastrow As Long
lastrow = Cells(Rows.Count, 1).End(xlUp).Row
For G = 4 To lastrow
AcctNb = Cells(G, 3).Value
Set myrange = Worksheets("MTL OR TOR").Range("AA4:AB685") 'Range in which the table MTL or TOR should be entered
result = Application.WorksheetFunction.VLookup(AcctNb, myrange, 2, False)
Range("K" & G).Value = result
Next
End Sub
Do you have any idea why is this code not working and how to fix it?
I was thinking maybe my error is in the line starting with Set myrange= Worksheets("MTL OR TOR") but couldn't figure it out.
Sub MTL_OR_TOR()
' Name your variables in a meaningful way and indicate their type
Dim strAcctNb As String
Dim strResult As String
Dim lngLastRow As Long
Dim lngLoop As Long
Dim rngLookup As Range
'Set your range and variables before you execute the code for readability
Set rngLookup = Worksheets("MTL OR TOR").Range("AA4:AB685") 'Range in which the table MTL or TOR should be entered
'Do not Activate or Select unless you really have to
'Worksheets("Master Filtered").Activate
With Worksheets("Master Filtered")
lngLastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
For lngLoop = 4 To lngLastRow
strAcctNb = .Cells(lngLoop, 3).Value
strResult = Application.WorksheetFunction.VLookup(strAcctNb, rngLookup, 2, False)
.Range("K" & lngLoop).Value = strResult
Next
End With
End Sub

Excel VBA offset function

I have an Excel file with information in column A and column B. Since these columns could vary in the number of rows I would like to use the function offset so that I could print the formula in one time as an array rather than looping over the formula per cell (the dataset contains almost 1 million datapoints).
My code is actually working the way I want it to be I only can't figure out how to print the code in Range(D1:D5). The outcome is now printed in Range(D1:H1). Anybody familiar how to use this offset within a for statement?
Sub checkOffset()
Dim example As Range
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Set example = Range("A1:A1")
For i = 1 To LastRow
example.Offset(0, i + 2).Formula = "=SUM(A" & i & ":B" & i & ")"
Next i
End Sub
Using the Offset(Row, Column), you want to offset with the increment of row (i -1), and 3 columns to the right (from column "A" to column "D")
Try the modified code below:
Set example = Range("A1")
For i = 1 To LastRow
example.Offset(i - 1, 3).Formula = "=SUM(A" & i & ":B" & i & ")"
Next i
One way of outputting the formula in one step, without looping, to the entire range, is to use the R1C1 notation:
Edit: Code modified to properly qualify worksheet references
Option Explicit
Sub checkOffset()
Dim example As Range
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
With sht
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set example = .Range(.Cells(1, 1), .Cells(LastRow, 1))
End With
example.Offset(columnoffset:=3).FormulaR1C1 = "=sum(rc[-3],rc[-2])"
End Sub
You don't need to use VBA for this. Simply type =sum(A1:B1) in cell D1 and then fill it down.
If you're going to use VBA anyway, use this:
Sub checkOffset()
Dim example As Range
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Set example = Range("A1:A1")
For i = 1 To LastRow
example.Offset(i - 1, 3).Formula = "=SUM(A" & i & ":B" & i & ")"
Next i
End Sub
The way offset works is with row offset, column offset. You want the column to always be fixed at 3 to the right.

Resources