I'm trying to delete specific range based on a time value in the column "J" . So far I got this:
Dim wb As Workbook
Dim c As Range
Dim zakres As Range
Dim zakres2 As Range
Dim all As String
Dim all2 As Range
Dim ile As String
Dim czas As Range
Set wb = ThisWorkbook
Set czas = wb.Worksheets("Dane").Range("J2")
ile = Application.WorksheetFunction.CountA(wb.Worksheets("Dane").Range("L:L"))
For i = 1 To ile
If czas.Value < "00:01:00" Then
Set zakres = czas.Offset(0, 0)
Set zakres2 = czas.Offset(0, 2)
all = zakres.Address & ":" & zakres2.Address
Set all2 = Range(all)
all2.Delete Shift:=xlUp
Else
Set czas = czas.Offset(1, 0)
End If
Next i
In the line If czas.Value < "00:01:00" Then I'm getting the 424 run time error - Object required.
It confuses me, since the variable czas is already declared...
Any ideas why it's happening and how to deal with it ?
When you delete the row that contains the range czas you also delete that range object. A null range has no property .value which is why you are getting an object required error.
A good way to mass delete range object is to use union to create non-contiguous ranges and then delete them all at once. This spares you the weirdness of shifting rows in a loop and also will significantly improve speed as deleting is pretty expensive.
Dim wb As Workbook
Dim c As Range
Dim zakres As Range
Dim zakres2 As Range
Dim ile As String
Dim czas As Range
Dim i As Long
Dim delrng As Range
Set wb = ThisWorkbook
Set czas = wb.Worksheets("Dane").Range("J2")
ile = Application.WorksheetFunction.CountA(wb.Worksheets("Dane").Range("L:L"))
For i = 1 To ile
If czas.Value < "00:01:00" Then
Set zakres = czas.Offset(0, 0)
Set zakres2 = czas.Offset(0, 2)
If delrng Is Nothing Then
Set delrng = Range(zakres, zakres2)
Else
Set delrng = Union(delrng, Range(zakres, zakres2))
End If
End If
Set czas = czas.Offset(1, 0)
Next i
If Not delrng Is Nothing Then
delrng.Delete
end if
Related
I'm working on simplifying an excel worksheet and I want information in the rows to be transferred based on the value. If the value = "done", I want it transferred to Carc. If the value = "On-going", I want it transferred to Ccon (haven't typed this up yet). This have been written-up in VBA but I'm open to trying other things if it would make things easier.
Main thing is that I'm trying to find a way to make the code already made, simpler and more practical. Only thing I haven't figured out is how to have it select 1 individual row, instead of all rows.
Sub MoveBasedOnValue2()
Dim TakeCell As Range
Dim DestCell As Range
Dim Status As Range
Dim Cjob As Worksheet
Dim CArc As Worksheet
Dim Contact As Range, Subject As Range, JobNo As Range, QuoteNo As Range
Dim Dateofcommision As Range, Ddate As Range
Set Cjob = Sheet4
Set CArc = Sheet1
If Cjob.Range("G2") = "Done" Then
Set Contact = Cjob.Range("A2")
Set Subject = Cjob.Range("B2")
Set QuoteNo = Cjob.Range("C2")
Set JobNo = Cjob.Range("D2")
Set Dateofcommision = Cjob.Range("E2")
Set Ddate = Cjob.Range("F2")
Status.Select
Contact.Select
Subject.Select
QuoteNo.Select
JobNo.Select
Dateofcommision.Select
Ddate.Select
If CArc.Range("A2") = "" Then
Set DestCell = CArc.Range("A2")
Else
Set DestCell = CArc.Range("A1").End(xlDown).Offset(1, 0)
End If
Contact.Copy DestCell
Subject.Copy DestCell.Offset(0, 1)
QuoteNo.Copy DestCell.Offset(0, 2)
JobNo.Copy DestCell.Offset(0, 3)
Dateofcommision.Copy DestCell.Offset(0, 4)
Ddate.Copy DestCell.Offset(0, 5)
Status.ClearContents
Contact.ClearContents
Subject.ClearContents
QuoteNo.ClearContents
JobNo.ClearContents
Dateofcommision.ClearContents
Ddate.ClearContents
End If
You can do something like this:
Sub MoveBasedOnValue2()
Dim cStatus As Range, wsDest As Worksheet
Set cStatus = Sheet4.Range("G2") 'first cell to check status
Do While Len(cStatus.Value) > 0
Select Case LCase(cStatus.Value)
Case "done": Set wsDest = Sheet1
Case "on-going": Set wsDest = Sheet2 'for example
Case Else: Set wsDest = Nothing 'no move to make
End Select
If Not wsDest Is Nothing Then 'got a destination sheet?
'here Range("A1:F2") is *relative* to the whole row...
cStatus.EntireRow.Range("A1:F2").Cut _
Destination:=wsDest.Cells(Rows.Count, "A").End(xlUp).Offset(1)
End If
Set cStatus = cStatus.Offset(1, 0) 'next source row
Loop
End Sub
I am trying to add values from a specific range(column) into a listbox. However, the range has blank cells and duplicates that I am trying to get rid of. The following code works (no error msg) and does populate the listbox, but it does not get rid of the duplicates.
Can someone help?
Private Sub UserForm_Initialize()
Dim rang, rang1 As Range
Dim lstrow As Long
Dim list(), ListUniq() As Variant
Dim iRw As Integer
Dim wb As Workbook
Dim ws As Worksheet
Dim x As Long
Set wb = ThisWorkbook
Set ws = wb.Sheets("Paramed Verification Grid")
Set rang = ws.Range("E3").CurrentRegion
lstrow = rang.Rows.Count + 1
Set rang1 = Range("E3:E" & lstrow)
'list = ws.Range("E3:E" & lstrow).SpecialCells(xlCellTypeConstants)
'Resize Array prior to loading data
ReDim list(WorksheetFunction.CountA(rang1))
'Loop through each cell in Range and store value in Array
x = 0
For Each cell In rang1
If cell <> "" Then
list(x) = cell.Value
x = x + 1
End If
Next cell
ListUniq = WorksheetFunction.Unique(list)
ListUniq = WorksheetFunction.Sort(ListUniq)
ProviderListBx.list = ListUniq
End Sub
I'm creating a dictionary from multiple worksheets and ranges.
My code is working, but is very unpleasant to look at.
There should be something fundamental missing in my knowledge, which is not surprise, as this is my first project in VBA.
How to achieve this in a single loop?
Any help is highly appreciated.
' Get the range of all the adjacent data using CurrentRegion
Dim rg1 As Range, rg2 As Range, rg3 As Range, rg4 As Range, rg5 As Range, rg6 As Range, rg7 As Range
Set rg1 = sheet1.Range("A1").CurrentRegion
Set rg2 = sheet2.Range("A1").CurrentRegion
Set rg3 = sheet3.Range("A1").CurrentRegion
Set rg4 = sheet4.Range("A1").CurrentRegion
Set rg5 = sheet5.Range("A1").CurrentRegion
Set rg6 = sheet6.Range("A1").CurrentRegion
Set rg7 = sheet7.Range("A1").CurrentRegion
Dim oID As clsItem, i As Long, j As Long, Id As Long
'read through the data
For i = 3 To rg1.rows.count
Id = rg1.Cells(i, 1).value
' Create a new clsDetector object
Set oID = New clsItem
' Add the new clsDetector object to the dictionary
dictName.add Id, oID
' Set the values
oID.ItemName = rg1.Cells(i, 70).value
Next i
'
'
'Same loops for rg2, rg3, rg4, rh5, rg6 and rg7
'
'
Since the sheets goes from 1 to 7 you can loop through them like this.
Sub LoadRangesIntoDict()
Dim i As Integer
Dim s As Integer
Dim ws As Worksheet
Dim rng As Range
Dim oID As clsItem, i As Long, j As Long, Id As Long
' Loop through each sheet
For s = 1 To 7
Set ws = Sheets("Sheet" & s)
Set rng = ws.Range("A1").CurrentRegion
'read through the data
For i = 3 To rng.Rows.Count
Id = rng.Cells(i, 1).Value
' Create a new clsDetector object
Set oID = New clsItem
' Add the new clsDetector object to the dictionary
dictName.Add Id, oID
' Set the values
oID.ItemName = rng.Cells(i, 70).Value
Next i
Next s
End Sub
I'm working with two workbooks. In the first I search for the value in the cell to the right of "Charge Number". Take that value and search the second workbooks pivot table for the matching row, copy it and go back to first work book and paste the data. This works great once. But I'm unable to get a loop to look for the next instance of "Charge Number" and repeat the process. The loop I have in the code isn't right because it finds the first value fine but then searches every next row for the same Charge Number.
Sub FindChargeNo()
Dim Loc As Range
Dim ChgNum As String
Dim SrchRng2 As String
Dim pvt As PivotTable
Dim wb As Workbook, ws As Worksheet
Dim FstWB As Workbook
Dim SecWB As Workbook
Dim rng As Range
Set FstWB = Workbooks("First.xlsm")
Set SecWB = Workbooks("Second_test.xlsx")
Set ws1 = FstWB.Worksheets("New Development")
Set ws = SecWB.Worksheets("Aug 18 Report")
Set pvt = ws.PivotTables(1)
lastRow = FstWB.Worksheets("New Development").Range("J" & Rows.Count).End(xlUp).Row
For i = 1 To lastRow
Set Loc = ws1.Cells.Find(What:="Charge Number")
If Not Loc Is Nothing Then
ChgNum = Loc.Offset(0, 1).Value
Debug.Print ChgNum
Debug.Print SrchRng
With pvt.PivotFields("Project WBS").PivotItems(ChgNum).LabelRange
Set rng = ws.Range(.Resize(.Rows.Count, pvt.TableRange1.Columns.Count).Address)
ws.Range(rng.Address).Copy
End With
SrchRng2 = Loc.Offset(0, 5).Address
FstWB.Worksheets("New Development").Range(SrchRng2).PasteSpecial
Set Loc = ws1.Cells.FindNext(Loc)
Loop While Loc.Address <> firstAddress
End If
Next
End Sub
I'm very new to VBA and should probably spend some time on debugging and learning the formalities of how code should be written.
I am using a loop that uses the Hlookup function to populate a table from on one sheet from data on a master sheet. (This is in the Sub SetMatrix). Within the Sub that performs this task I use some other UDF's, one which copies and pastes the variables (names from a 3rd sheet which may change) I want to lookup from the master sheet.
In any case it runs perfectly fine when the I use a hardcoded number for the row in the lookup function. However, once I try to use a variable (jpmRow instead of a number like 50) for the row it will work the first time only. Then when I run it again I get RunTime error 91 - object variable or withblock variable not set. The debugger take me back to the DynamicRange UDF, Set StartCell line, which confuses me because that is not where I am setting the row variable. Meanwhile if I use a constant for the row it lets me rerun the sub with success every time.
Here is the code:
Option Explicit
Dim wsTemplate As Worksheet
Dim ws As Worksheet
Dim TxtCell As Range
Dim PortfolioCell As String
Dim StartCell As Range
Dim EndCell As Range
Dim RangeParameter As Range
Dim jpmRow As Integer
Dim myColumn As Integer
Dim myRow As Integer
Function DynamicRange(TxtToFind As String) As Range
Dim k As Integer
k = iCount
Set ws = Sheets("Template")
Set StartCell = ws.Cells.Find(TxtToFind).Offset(2, 0)
myColumn = StartCell.Column
myRow = StartCell.Row
Set EndCell = ws.Cells(myRow + k - 1, myColumn)
Set DynamicRange = ws.Range(StartCell.Address, EndCell.Address)
'Set DynamicRange = RangeParameter
End Function
Function iCount() As Integer
Set ws = Sheets("Template")
Set StartCell = ws.Cells.Find("Ticker").Offset(2, 0)
Set EndCell = ws.Cells.Find("Total").Offset(-1, 0)
iCount = ws.Range(StartCell.Address, EndCell.Address).Rows.Count
End Function
Sub SetMatrix()
Dim StartTable As Range
Dim iRows As Range
Dim iColumns As Range
Dim myArray(50, 50) As Integer
Dim wsJPM As Worksheet
Dim i As Integer
Dim j As Integer
Set StartTable = Sheets("Correlation Matrix").Range("A3")
Set iRows = Range(StartTable.Offset(1, 0).Address, StartTable.Offset(iCount, 0).Address)
Set iColumns = Range(StartTable.Offset(0, 1).Address, StartTable.Offset(0, iCount).Address)
Set wsJPM = Sheets("JPM")
Sheets("Correlation Matrix").Cells.ClearContents
Sheets("Correlation Matrix").Cells.ClearFormats
DynamicRange("Asset Class").Copy iRows
DynamicRange("Asset Class").Copy
iColumns.PasteSpecial Transpose:=True
For i = 1 To iCount
For j = 1 To iCount
jpmRow = wsJPM.Cells.Find(StartTable.Offset(i, 0), SearchOrder:=xlColumns, LookAt:=xlWhole).Row
StartTable.Offset(i, j).Value = Application.WorksheetFunction.HLookup(StartTable.Offset(0, j), Sheets("JPM").Range("B1:BZ100"), jpmRow, False)
Next j
Next i
End Sub