Update Table (ListObject) Row Values, based on first cell value - excel

I want to update data in any table using this format:
Dim Update As String
Dim FindUpdate As Range
Update = Range("USER_NAME").value
With Sheets("Settings")
Set FindUpdate = .Range("USERS_TABLE").Find(What:=Update, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext)
.Cells(FindUpdate.row, 6).value = Computer
End With
This code works but it requires me to put this table at the beginning of the Sheet.
I want to change values in a table (ListObjects("USERS_TABLE")) regardless of where it's positioned in the worksheet. Changing the range to a table's name USERS_TABLE did not do the trick.
Ideally I want to change the above code to:
Dim Update As String
Update = Range("USER_NAME").value ' This is a Namedrange
' declare a variables that will point to a table I want to access
dim ws as Worksheet
Set ws = ActiveSheet
Dim table_row as ListRow
Set table_row = ws.ListObject("USERS_TABLE").ListRows.**SOMETHING_TO_HELP_ACCESS_THE_TABLE_ROW_HERE**
Dim FindUpdate As Range
With table_row ' REPLACE SHEETS WITH TABLE_ROW
Set FindUpdate = .**Row?**.Find(What:=Update, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext)
' AND CAUSE IT'S A TABLE, MAYBE A COLUMN HERE?
.**Cells(or Range)?**(FindUpdate.**row**, 6).value = Computer
End With

TO #VBasic2008, sorry for the confusion, but... This is what I have... It works I can add rows using this
Public Sub Add_Table_Row()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim add_row As ListRow
Set add_row = ws.ListObjects("Names_Table").ListRows.Add(1)
With add_row
.Range(3) = "Sample Text"
End With
End Sub
I want to use the above method to update Table values, like this...
Public Sub Update_Table_Row()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim update_row As ListRow
Set update_row = ws.ListObjects("Names_Table").ListRows ' STUCK HERE
With update_row
.Range(3) = "Change This Text"
End With
End Sub

is it work?
Public Sub Update_Table_Row()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim update_row As ListRow
Set update_row = ws.ListObjects("Names_Table").ListRows ' STUCK HERE
With update_row
.Range(3) = "Change This Text"
End With
End Sub

Sorry for the late reply... Found a simple solution to ADD and UPDATE a Table (ListObjects.ListRow) Row
1. Add Table Row with values
Sub Add_Product()
' Declare Products Database Variable
Dim Products_Table As ListObject
Set Products_Table = Sheets("Products").ListObjects("PRODUCT_DATABASE")
' Declare Add Product Variable
Dim Product_New_Row As ListRow
Set Product_New_Row = Products_Table.ListRows.Add(1)
With Product_New_Row
.Range(1) = "PRODUCTSKU01" ' 1st Column
.Range(2) = "New Product Name" ' 2nd Column
.Range(5) = 1000 ' 5th Column
End With
End Sub
2. Change Table Row Values
Sub Update_Product()
' Declare Products Database Variable
Dim Products_Table As ListObject
Set Products_Table = Sheets("Products").ListObjects("PRODUCT_DATABASE")
' Declare Search Value
Dim Find_Value As String
Find_Value = "PRODUCTSKU01" ' 1st Column of the Products Database
' Declare Product Row
Dim Product_Update_Row As Range
Set Product_Update_Row = Products_Table.DataBodyRange.Find( _
What:=Find_Value, _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext _
)
' Update Product
With Product_Update_Row
' Change column # value
.Cells(1, 2).value = "Change Product Name"
End With
End Sub

Related

Find Next Method Slow on Last Instance only

all.
I'm running this code:
Sub ISN_Flyer_Performance()
Dim FlyerSh As Worksheet
Dim QlikSh As Worksheet
Dim SKURng As Range
Dim QlikSKURng As Range
Dim SKU As Range
Dim qlr As Long
Dim QlikSKU As Range
Dim TotalSales As Double
Dim FirstQlikSku As Range
Set FlyerSh = ActiveSheet
i = 2
lr = FlyerSh.Range("A" & Rows.Count).End(xlUp).Row
Set QlikSh = Application.InputBox("Click any cell on the Qlikview Sheet you want to lookup against", "Find Qlikview Sheet", Type:=8).Worksheet
qlr = QlikSh.Range("A" & Rows.Count).End(xlUp).Row
Set QlikSKURng = Range(Cells(2, QlikSh.Rows(1).Find(What:="Item Number", LookAt:=xlWhole).Column), Cells(qlr, QlikSh.Rows(1).Find(What:="Item Number", LookAt:=xlWhole).Column))
Set SKURng = Range(FlyerSh.Cells(i, 1), FlyerSh.Cells(lr, 1))
Set SKU = FlyerSh.Cells(i, 1)
For Each SKU In SKURng
Set QlikSKU = QlikSKURng.Find(What:=SKU.Value, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)
If QlikSKU Is Nothing Then
SKU.Offset(0, 2).Value = 0
GoTo NextSku
Else
TotalSales = QlikSKU.Offset(0, 5).Value
Set FirstQlikSku = QlikSKU
Do
Set QlikSKU = QlikSKURng.FindNext(QlikSKU)
If QlikSKU.Address = FirstQlikSku.Address Then Exit Do
TotalSales = TotalSales + QlikSKU.Offset(0, 5).Value
Loop
SKU.Offset(0, 2) = TotalSales
End If
NextSku:
Next SKU
End Sub
It's essentially like an XLookup, where it gets the thing to seach on one workbook, then finds it on a second, sends the value back to the first one, and moves on to the next item. I'd use an XLookup, but unfortunately, my sheet will always have duplicates, and I need to count both.
So I'm using this findnext loop to loop through a range (QlikSKURange) which has about 16k rows. The findNext is reasonably quick, like less than a second, EXCEPT the last instance when it goes back to the beginning and finds the first instance again. That instance can take over ten seconds.
Any idea why that might be?
Let me know if you need more info about the code.
I tried to just "Find" after the current iteration, instead of find next, and it has the same slow down.
VBA Lookup Using the Find Method
This is just the basic idea. There are many flaws e.g. if you cancel the input box, if you select a 'wrong' worksheet (e.g. column header not found), if there are error values, blank cells, etc.
Option Explicit
Sub ISN_Flyer_Performance()
' Flyer
Dim fws As Worksheet: Set fws = ActiveSheet ' improve!
Dim fLR As Long: fLR = fws.Range("A" & fws.Rows.Count).End(xlUp).Row
Dim frg As Range
Set frg = fws.Range(fws.Cells(2, "A"), fws.Cells(fLR, "A"))
'Debug.Print fws.Name, fLR, frg.Address
' Qlikview
Dim qws As Worksheet: Set qws = Application.InputBox( _
"Click any cell on the Qlikview Sheet you want to lookup against", _
"Find Qlikview Sheet", Type:=8).Worksheet
Dim qLR As Long: qLR = qws.Range("A" & qws.Rows.Count).End(xlUp).Row
Dim qC As Long
With qws.Rows(1) ' assuming that "Item Number" is surely in the first row
qC = .Find("Item Number", .Cells(.Cells.Count), _
xlFormulas, xlWhole).Column
End With
Dim qrg As Range
Set qrg = qws.Range(qws.Cells(2, qC), qws.Cells(qLR, qC))
'Debug.Print qws.Name, qLR, qC, frg.Address
Application.ScreenUpdating = False
Dim fCell As Range
Dim qCell As Range
Dim qFirstAddress As String
Dim TotalSales As Double
' Loop.
For Each fCell In frg.Cells
Set qCell = qrg.Find(fCell.Value, qrg.Cells(qrg.Cells.Count), _
xlFormulas, xlWhole)
If qCell Is Nothing Then
fCell.Offset(0, 2).Value = 0
Else
qFirstAddress = qCell.Address
Do
TotalSales = TotalSales + qCell.Offset(0, 5).Value
Set qCell = qrg.FindNext(qCell)
Loop Until qCell.Address = qFirstAddress
fCell.Offset(0, 2).Value = TotalSales
TotalSales = 0
End If
Next fCell
Application.ScreenUpdating = True
MsgBox "Lookup done.", vbInformation
End Sub
After doing more digging, someone suggested that the issue was that one of my sheets was a table. It had filters on the header row. I removed those (and conditional formatting on a row to find duplicates, and my code ran in a matter of seconds. After isolating those two, turns out the conditional formatting was the culprit.

Using Variable/Range as Worksheet and Table name

I am working with a workbook where you can choose a list of countries in a dropdown menu.
When changing the name, the Pivot table is updated to the corresponding Worksheet and Table.
The Pivot updating works and it changes the source depending on the country chosen.
The next step is that I want some data from the table that we connected to the worksheet to do some calculations.
If I choose the name of the worksheet and table directly in the "set" step, they are not changing depending on my dropdown selection.
Sub NORDICS()
Dim tblName As String
Dim ws1 As Worksheet
Dim ams As Long
Dim Target As Variant
Dim average As Variant
Dim tbl As ListObject
Set ws1 = Worksheets("Nordics")
Set tbl = ws1.ListObjects("TableNordics")
''What is the Table Name
Range("E3").Formula = "=""Table""&F3"
''Set tblName to the "calculated" table name above
tblName = Range("E3")
''Update the source to "PivotTable1" to be the tblName
Application.CutCopyMode = False
ActiveSheet.PivotTables("PivotTable1").ChangePivotCache ActiveWorkbook. _
PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
tblName, Version:=6)
ActiveSheet.ChartObjects("Chart 1").Activate
ActiveChart.FullSeriesCollection(2).Points(53).Select
Selection.Format.Line.EndArrowheadStyle = msoArrowheadStealth
''Collect the Last row of the Table Body
ans = tbl.DataBodyRange.Rows.Count
''Collect the Last cell value of column 8 and last row calculated above
Target = tbl.DataBodyRange(ans, 8).Value
''Collect the Total Rows Value from the Table
With tbl
average = .TotalsRowRange.Cells(.ListColumns.Count).Value
End With
''Calculate the average vs Target value and put in "W3"
Range("W3") = average - Target
''Remove Calculations done on worksheet that is not needed any more
Range("E3").Formula = "="""""
Range("E3").Value = Range("E3").Value
End Sub
My end goal would be that
Set ws1 = Worksheets("Nordics")
Set tbl = ws1.ListObjects("TableNordics")
is
Set ws1 = Worksheets = Range("F3")
Set tbl = ws1.ListObjects = Range("E3")

How to find all in specific column and replace based on another worksheet column data?

I have two worksheets, one generated automatically by another Macro I already have, this one generates data in a new WorkSheet called "SheetN" where N is a numerical value that depends on how many times this macro has been executed.
Then, in my PrincipalSheet I have something like:
Column R
User1; User2; User3;
User2; User4;
User2; User3; User5; User6;
In my auto generated SheetN I have:
Column B
User3;
User2;
NAN
I want to be able to iterate through SheetN column B until is empty and make a find all based on every row that is not NAN and then replace with "" in the PrincipalSheet:
Column R
User1;
User4;
User5; User6;
So far I have an idea to do something like
Sub Test2()
Dim i As Integer
Dim max As Integer
i = 1
i = 20
While i < max
If IsNot IsEmpty(ThisWorkbook.Sheets(NewSheet).Cells(2, i)) Then
MsgBox ThisWorkbook.Sheets(NewSheet).Cells(2, i)
End If
i = i + 1
Wend
End Sub
To retrieve the values from SheetN but this is not working, I'd really appreciate some help.
In the code I admitted that in SheetN columnB you can have duplicate values.
Sub ReplaceUserWithBlank()
Dim ws1 As Worksheet: Set ws1 = Sheets("Principal")
Dim ws2 As Worksheet: Set ws2 = Sheets("SheetN")
Dim lRowColB As Long: lRowColB = ws2.Cells(Rows.Count, "B").End(xlUp).Row
Dim lRowColR As Long: lRowColR = ws1.Cells(Rows.Count, "R").End(xlUp).Row
Dim rngColB As Range: Set rngColB = ws2.Range("B2:B" & lRowColB)
Dim rngColR As Range: Set rngColR = ws1.Range("R2:R" & lRowColR)
Dim rngTemp As Range: Set rngTemp = ws2.Range("K2:K" & lRowColB)
' copy column B to temporary column 'K'
rngColB.Copy rngTemp
' set range in column 'K'
Set rngTemp = Range(rngTemp, rngTemp.End(xlDown))
' Remove dulipcates
rngTemp.RemoveDuplicates Columns:=1, Header:=xlNo
' reset rngTemp
Set rngTemp = ws2.Range("K2", ws2.[K2].End(xlDown))
' Replace with blank
Dim rCell As Range
For Each rCell In rngTemp
rngColR.Replace What:=rCell.Value, Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
Next rCell
' Trim and Clean
For Each rCell In rngColR
rCell.Value = Application.WorksheetFunction.Clean(Trim(rCell.Value))
Next rCell
' Clear temporary range 'K'
rngTemp.Clear
End Sub

Find string in one worksheet and select it in another

I've got Workbook where I got names and hours worked of employees. I'm looking for comparing rows in one worksheet (Range B6:CC6) and find it in another with selection on cell with employee name (Range A1:A5000) when I change sheets from 1 to 2.
Tried some Range.Find and others, no idea how to do it
Public Sub FindPosition()
Dim Actcol As Integer, Pos As Range, Name As Range
Actcol = ActiveCell.Column
MsgBox "ActiveCell is" & Actcol
Set Pos = Cells(6, Actcol)
MsgBox Pos
Pos.Select
If Worksheets("Sheet2").Activate Then
Worksheets("Sheet2").Range("A1:AA5100").Select
Set Name = Selection.Find(Pos, LookIn:=xlValues)
End If
End Sub
First, if you want to trigger some macro by activation of Sheet2, you need to handle Activate event of Sheet2. This can be done by declaring subroutine in Sheet module like this.
Private Sub Worksheet_Activate()
'Codes you want to be run when Sheet2 is activated.
End Sub
Second, a simple way to find a cell with specific value is to use WorksheetFunction.Match. For example,
Dim SearchInRange As Range
Set SearchInRange = Range("A1:A5000")
Dim EmployeeName As Variant
EmployeeName = ... 'Actual employee name you want to search
On Error GoTo NotFound
Dim Index As Variant
Index = WorksheetFunction.Match(EmployeeName, SearchInRange, 0)
On Error GoTo 0
SearchInRange.Cells(Index).Select
GoTo Finally
NotFound:
' Handle error
Finally:
Range.Find may also work, but remember it has the side effect of changing the state of "Find and Replace" dialog box.
This may helps you
Option Explicit
Sub test()
Dim i As Long, LastRowA As Long, LastRowB As Long
Dim rngSearchValues As Range, rngSearchArea As Range
Dim ws1 As Worksheet, ws2 As Worksheet
'Set you worksheets
With ThisWorkbook
'Let say in this worksheet you have the names & hours
Set ws1 = .Worksheets("Sheet1")
'Let say in this worksheet you have the list of names
Set ws2 = .Worksheets("Sheet2")
End With
'Find the last row of the column B with the names from the sheet with names & hours
LastRowB = ws1.Cells(ws1.Rows.Count, "B").End(xlUp).Row
'Find the last row of the column A with the names from the sheet with list of names
LastRowA = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row
'Set the range where you want to check if the name appears in
Set rngSearchArea = ws2.Range("A1:A" & LastRowA)
'Loop the all the names from the sheet with names and hours
For i = 6 To LastRowB
If ws1.Range("B" & i).Value <> "" Then
If Application.WorksheetFunction.CountIf(rngSearchArea, "=" & ws1.Range("B" & i).Value) > 0 Then
MsgBox "Value appears"
Exit For
End If
End If
Next i
End Sub
Oh right, I found solution. Thanks everyone for help.
Public Sub Position()
Dim Accol As Integer
Dim Pos As Range
Dim name As Range
ActiveSheet.name = "Sheet1"
Accol = ActiveCell.Column
Set Pos = Cells(6, Accol)
Worksheets("Sheet2").Activate
Worksheets("Sheet2").Range("a1:a5000").Select
Set name = Selection.Find(What:=Pos, After:=ActiveCell, LookIn:=xlValues, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
name.Select
End Sub
Last thing I would like to do which I cannot solve is where do I write automatically script running when I choose Sheet2?

Insert new row under a specific text using vba

I am trying to insert new row under a particular text(selected from userform) with the new text but getting an error "Object variable or With block variable not set" in the line "fvalue.Value = Me.txtremark.Value".
Please help me to find where exactly the mistake I did in the Code. I was trying to find many ways but failed.
Excel Table:
Required Output:
Private Sub cmdadd_Click()
Dim fvalue As Range
Dim wks As Worksheet
Set wks = ThisWorkbook.Worksheets("Sheet1")
wks.Activate
Set fvalue = wks.Range("B:B").Find(What:=Me.txtremark.Value, LookIn:=xlFormulas, LookAt:=xlWhole)
fvalue.Value = Me.txtremark.Value
fvalue.Offset(1).EntireRow.Insert Shift:=xlDown
fvalue.Offset(0, 1).Value = Me.txtplace.Value
End Sub
Try:
Option Explicit
Sub test()
Dim Position As Range, rngToSearch As Range
Dim strToFound As String
'Change strToFound value
strToFound = "Test"
With ThisWorkbook.Worksheets("Sheet1")
Set rngToSearch = .Range("B:B")
Set Position = rngToSearch.Find(strToFound, LookIn:=xlValues, Lookat:=xlWhole)
If Not Position Is Nothing Then
Debug.Print Position.Row
.Rows(Position.Row).Offset(1).EntireRow.Insert
End If
End With
End Sub
Try using a separate variable to pass values to the worksheet, or just refer to the textbox.
Additionally, activating (and selecting) is not necessary and will hurt your macro's speed and is prone to errors.
Option Explicit
Private Sub cmdadd_Click()
Dim fvalue As Range
Dim wks As Worksheet
Set wks = ThisWorkbook.Worksheets("Sheet1")
Set fvalue = wks.Range("B:B").Find(What:=Me.txtremark.Value, LookIn:=xlFormulas, LookAt:=xlWhole)
If Not fvalue Is Nothing Then
wks.Rows(fvalue.Row + 1).EntireRow.Insert
wks.Cells(fvalue.Row + 1, fvalue.Column + 1).Value = Me.txtremark.Value
End If
End Sub
I have taken the liberty to check if the value is found in the first place

Resources