I am having problems with my code. I am trying to inset values into a "database" by using the find function to identify the correct rownumber. when i run the code the find function returns the next rownumber ie. the serchname is in row 300 but the data is inserted in row 301.
the code i am using is as follows:
For Each Cell In Workbooks(controlfile).Sheets("Lab").Range("B9:B56")
If Cell.Value <> "" Then
'Range("N" & latestRow).Value = Right(DataArray(1), 4) & Right(DataArray(2), 4)
'Range("N" & latestRow).NumberFormat = "00000000"
søgeOrd = Right(Cell.Value, 4) & Right(Cell.Offset(0, 1), 4)
Workbooks(controlfile).Sheets("Lab").Range("A1").Value = søgeOrd
Workbooks(controlfile).Sheets("Lab").Range("A1").NumberFormat = "00000000"
LinjeL = Cell.Row
FGM = Workbooks(controlfile).Sheets("Lab").Range("F" & LinjeL).Value
STA = Workbooks(controlfile).Sheets("Lab").Range("I" & LinjeL).Value
BMK = Workbooks(controlfile).Sheets("Lab").Range("J" & LinjeL).Value
VK = Workbooks(controlfile).Sheets("Lab").Range("L" & LinjeL).Value
DP = Workbooks(controlfile).Sheets("Lab").Range("M" & LinjeL).Value
SNB = Workbooks(controlfile).Sheets("Lab").Range("N" & LinjeL).Value
Workbooks(controlfile).Sheets("Lab").Range("A1").ClearContents
'find søgeord i database og indsæt de værdier som er fundet i lab
Workbooks(FileName).Sheets("Database").Activate
Columns("N:N").Select
Set cellD = Selection.Find(What:=Workbooks(controlfile).Sheets("Lab").Range("A1").Value, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not cellD Is Nothing Then LinjeD = cellD.Row
If Range("E" & LinjeD).Value <> "" Then
'kopier alle data til fejllog hvis der allerede er data
Range("A" & LinjeD).Select
ActiveCell.EntireRow.Copy
Workbooks(FileName).Worksheets("Fejllog").Activate
LastLine = Workbooks(FileName).Sheets("Fejllog").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Row
Range("A" & LastLine).PasteSpecial
Application.CutCopyMode = False
Workbooks(FileName).Sheets("Database").Activate
Range("E" & LinjeD).Value = FGM
Range("H" & LinjeD).Value = STA
Range("I" & LinjeD).Value = BMK
Range("O" & LinjeD).Value = Format(Now, "dd.mm.yyyy")
Range("P" & LinjeD).Value = VK
Range("Q" & LinjeD).Value = DP
Range("R" & LinjeD).Value = SNB
Workbooks(controlfile).Sheets("Lab").Activate
Else
Range("E" & LinjeD).Value = FGM
Range("H" & LinjeD).Value = STA
Range("I" & LinjeD).Value = BMK
Range("O" & LinjeD).Value = Format(Now, "dd.mm.yyyy")
Range("P" & LinjeD).Value = VK
Range("Q" & LinjeD).Value = DP
Range("R" & LinjeD).Value = SNB
Workbooks(controlfile).Sheets("Lab").Activate
End If
End If
Next Cell
Any input would be greatly appreciated, thank you.
I re-wrote your code to eliminate use of the Selection object.
Private Sub Snippet()
Dim WsDb As Worksheet
Dim ClmN As Range
Dim cellID As Range
Dim What As Variant
Dim LineID As Long
What = Workbooks(controlfile).Sheets("Lab").Range("A1").Value
Set WsDb = Workbooks(Filename).Sheets("Database")
Set ClmN = WsDb.Columns("N:N")
Set cellD = ClmN.Find(What:=What, After:=ActiveCell, _
LookIn:=xlFormulas, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not cellD Is Nothing Then LinjeD = cellD.Row
End Sub
Observe how the definition of the worksheet on which you do your search is now done by declaring a variable for it. The code will now work smoothly in the background without screen flickering.
Now you can blame me for destroying your reference to the ActiveCell. Did I really? Which cell was active in your code when the Database tab was activated? Could have been anyone or none. Now the code will crash because the ActiveCell isn't in the ClmN range. Obviously, you need to specify a cell in that range for starting the search.
Does the cellID range start in a row other than where What was found? I doubt it and you don't claim so, either. You say that a row gets inserted at a point other than LineID. That is normal and has to do with the action of inserting a row, not related to the code you published. Logically, the new row should take the place of the one you specified. Therefore the cellId.Row would now be one row lower than before. However, I got this wrong many times. Therefore I always test which row is the old and which one the new. It's not difficult - and it's always the same.
I have found the solution.
I had mistakenly cleared the content of the cell used as the search name before the search began. this resulted in a search for an empty cell.
Thank you to all of you for making inputs, and helping me clean up my code :)
It is amazing how you can spend hours looking at something, only to find the answer is right in front of you.
Related
The below code works as long as there are more than one instance of the search criteria. However, if there is only one row that is listed as the what in the find function I receive the error "Could not set the list property. Invalid property array index"
Private Sub UserForm_Initialize()
Dim iRow As Integer, iMax As Integer
iRow = Cells.Find(What:="New Jersey Audit Adjustment", _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Row
iMax = Cells.Find(What:="New Jersey Audit Adjustment", _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, _
MatchCase:=False, SearchFormat:=False).Row
Me.ComboBox1.List = Worksheets("C-Proposal-19").Range("B" & iRow & ":B" & iMax).Value
Me.ComboBox2.List = Worksheets("C-Proposal-19").Range("B" & iRow & ":B" & iMax).Value
Me.ComboBox3.List = Worksheets("C-Proposal-19").Range("B" & iRow & ":B" & iMax).Value
Me.ComboBox4.List = Worksheets("C-Proposal-19").Range("B" & iRow & ":B" & iMax).Value
Me.ComboBox5.List = Worksheets("C-Proposal-19").Range("B" & iRow & ":B" & iMax).Value
End Sub
The error occurs here Me.ComboBox1.List = Worksheets("C-Proposal-19").Range("B" & iRow & ":B" & iMax).Value if I have one row listed with "New Jersey Audit Adjustment"
When your range contains one cell, the .value will give you a value instead of an array. As the .list expects an array you could fill an array with one element or use addItem (see below)
If Worksheets("C-Proposal-19").Range("B" & iRow & ":B" & iMax).Cells.Count = 1 Then
Me.ComboBox1.AddItem Worksheets("C-Proposal-19").Range("B" & iRow & ":B" & iMax).Value
Else
Me.ComboBox1.List = Worksheets("C-Proposal-19").Range("B" & iRow & ":B" & iMax).Value
End If
I'am trying to replace . to / on selection but after replace some cell not change. I have to change it mannual by click enter. Please suggest it via VBA. for change. I also try to calculate and numberformat but both are not working
Sub Reverse_Cheque()
Dim ChequeDate As String, i As Long
i = 2
'Debug.Print ChequeDate.Address
Range("A1").CurrentRegion.Columns.AutoFit
Range("L:L").Insert
Range("L1").Value = "expire date"
Do Until Range("k" & i).Value = ""
ChequeDate = Range("K" & i).Value
Range("k" & i).Value = Replace(Range("k" & i).Value, ".", "/")
Range("k" & i).NumberFormat = "dd-mm-yyy"
'Range("L" & i).Value = Range("k" & i).Value + 89
i = i + 1
Loop
End Sub
Range("k" & i).Value = Replace(Range("k" & i).Value, ".", "/")
Range("k" & i).NumberFormat = "dd-mm-yyy"
This is not the right way to do it. This will only work if the previous number format is "General". This is an example to replicate the above issue. The below will not work.
[A1].NumberFormat = "#"
[A1].Value = #1/1/2021#
[A1].NumberFormat = "dd/mm/yyyy"
For the above to work, you will have to press F2 and then Enter.
The below will work without F2 and Enter
[A1].NumberFormat = "General"
[A1].Value = #1/1/2021#
[A1].NumberFormat = "dd/mm/yyyy"
And hence it is always advisable to change the number format first before inputing new data.
Also you do not need a loop. You can use .Replace to replace all . in one go. Here is an example. Change it to suit your needs.
With Columns("K")
.NumberFormat = "dd/mm/yyyy"
.Replace What:=".", Replacement:="/", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
End With
I am using excel to automate data cleaning. I want to create a column called "Group 1". I have another column First Name and another called Last Name. If the first name and last name is empty fill the Group 1 column with yes.
These two worked for me...
Hope this helps, you don't need VB6 for this:
Sub Macro1()
With ActiveWorkbook.Sheets(1):
LastRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
For i = 2 To LastRow
If Range("A" & i) = "" Or Range("B" & i) = "" Then
Range("C" & i) = "No"
Else: Range("C" & i) = "Yes"
End If
Next
End With
End Sub
Sub Macro2()
With ActiveWorkbook.Sheets(1):
LastRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Range("C2").FormulaR1C1 = "=+IF(CONCATENATE(RC[-2]&RC[-1])="""",""Yes"",""No"")"
Range("C2").AutoFill Destination:=Range("C2:C" & LastRow)
End With
End Sub
I am attempting to use variables in what should be a simple addition formula. First I search for the column header in row 3 call "Jan Expense Hours" MsgBox ColL comes back with the letter "I" and MsgBox ColL2 comes back with the letter "J", both of which are correct. lRow comes back with row 55 which is also correct. Although when I try to add these variables to Worksheets("Calcs").Range("F4:F" & lRow).Formula = "=SUM('Resource Details'! & [ColL] & 4: & [ColL2] & 4)" I get an Application-defined or object-defined error on this line of code. Does anyone have an Idea what I am doing wrong? Btw, I'm searching for the column header because the columns do shift on various copies.
Full Procedure:
Sub JanTotHrsFind()
Dim lRow As Long
Dim lCol As Long
Dim strSearch As String
Dim aCell As Range
Dim ColL As String
Dim ColL2 As String
Dim ColNo As Long
Sheets("Resource Details").Activate
'find the column
strSearch = "*Jan Expense Hours*"
Set aCell = Sheets("Resource Details").Rows(3).Find(What:=strSearch, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
'convert column number to letter
ColNo = aCell.Column
ColL = Split(Cells(, ColNo).Address, "$")(1)
ColL2 = Split(Cells(, (ColNo + 1)).Address, "$")(1) 'adds one more column to right
MsgBox ColL
MsgBox ColL2
lRow = Cells.Find(What:="SUBTOTAL*", _
After:=Range(ColL & "4"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row - 1 'minus 1 row to move above
MsgBox "Last Row: " & lRow
'formula for Jan Expense Hours + Jan Capital Hours
'Worksheets("Calcs").Range("F4:F" & lRow).Formula = "=SUM('Resource Details'!I4:J4)"
'Worksheets("Calcs").Range("F4:F" & lRow).Formula = "=SUM('Resource Details'![" & ColL & "]4:[" & ColL2 & "]4)"
Worksheets("Calcs").Range("F4:F" & lRow).Formula = "=SUM('Resource Details'! & [ColL] & 4: & [ColL2] & 4)"
End Sub
You should not write your variables within brackets.
So:
Worksheets("Calcs").Range("F4:F" & lRow).Formula = "=SUM('Resource Details'!" & [ColL] & "4:" & [ColL2] & "4)"
Can you please try your code as I corrected above and see how it goes.
I have an excel file full of adresses which I need to import in our system.
the housenumber column is formatted like this:
Normal house numbers just show the number but house numbers with a certain boxnumber are shown like this: 25 B12
I need to get the boxnumbers (if they exist) in another column
I managed to do this with these functions
Function GetBus(Text As String, ByRef NumberCell As Range) As String
Dim LastWord As String
LastWord = ReturnLastWord(Text)
If Left(LastWord, 1) = "B" Then
GetBus = Right(LastWord, Len(LastWord) - 1)
Else
GetBus = ""
End If
End Function
Function ReturnLastWord(Text As String) As String
Dim LastWord As String
LastWord = StrReverse(Text)
LastWord = Left(LastWord, InStr(1, LastWord, " ", vbTextCompare))
ReturnLastWord = StrReverse(Trim(LastWord))
End Function
So creating the new column with the box values is working. What is not working is deleting the box part in the number column (fe: if number value is 25 B1 the B1 part should be removed)
Any Ideas of how to do this or is this not possible in excel?
This is something which I wrote couple of years ago so I am not sure if there are bugs in it but a quick test seems to portray that it is working correctly. You might have to change it to make it exactly work in your situation.
Code:
Option Explicit
Sub SplitAddress()
Dim MyAr() As String, tempStr As String, strUnique As String
Dim lRow As Long, i As Long, j As Long, lRow2 As Long
Dim cell As Range
strUnique = "SiddR" & Format(Now, "ddmmyyhhmmss")
With ActiveSheet
.Columns("A:A").Replace What:=" ", Replacement:=strUnique, LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Columns("C").NumberFormat = "#"
.Columns("D").NumberFormat = "#"
For i = 2 To lRow
MyAr = Split(.Range("A" & i).Value, strUnique)
tempStr = ""
For j = LBound(MyAr) To (UBound(MyAr) - 1)
If tempStr = "" Then
tempStr = MyAr(j)
Else
tempStr = tempStr & " " & MyAr(j)
End If
Next j
.Range("B" & i).Value = tempStr
.Range("C" & i).Value = MyAr(UBound(MyAr))
Next i
For i = 2 To lRow
If Not IsNumeric(.Range("C" & i).Value) Then
tempStr = ""
For j = 1 To Len(.Range("C" & i).Value)
If IsNumeric(Mid(.Range("C" & i).Value, j, 1)) Then
If tempStr = "" Then
tempStr = Mid(.Range("C" & i).Value, j, 1)
Else
tempStr = tempStr & Mid(.Range("C" & i).Value, j, 1)
End If
Else
Exit For
End If
Next
.Range("D" & i).Value = Mid(.Range("C" & i).Value, j)
.Range("C" & i).Value = tempStr
If Len(Trim(tempStr)) = 0 Then
MyAr = Split(.Range("A" & i).Value, strUnique)
.Range("C" & i).Value = MyAr(UBound(MyAr) - 1)
End If
End If
Next
.Columns("A:A").Replace What:=strUnique, Replacement:=" ", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
.Columns("D:D").Replace What:="-", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
End With
End Sub
Screenshot:
Screenshot:
With your test data
EDIT: Now when I look at this code again, I see that it can be optimized much much further :)