I wrote an Excel macro and it seems to work fine. It displays an inputbox and once I give the value in it. It saves that value into first cell of column C (C1). However the second time I run macro I want it to be written into C2 and keep all datas in different rows in column C but each time, it writes it into C1 and cause a data loss.
Sub DataInput()
Dim SearchTarget As String
Dim myRow As Long
Dim Rng As Range
Static PrevCell As Range
Dim FoundCell As Range
Dim CurCell As Range
Dim a As String
Dim Target As Range
'SearchTarget = "asdf"
SearchTarget = InputBox("Scan or type product barcode...", "New State Entry")
If PrevCell Is Nothing Then
myRow = Selection.Row
Set PrevCell = Range("C" & myRow)
End If
'Set Rng = Range("C:C,E:E") 'Columns for search defined here
Set Rng = Range("C:C,C:C") 'Columns for search defined here
With Rng
Set FoundCell = .Cells.Find(What:=SearchTarget, _
After:=PrevCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=True)
End With
If FoundCell Is Nothing Then
MsgBox SearchTarget & " was not found."
Range("C1").Value = InputBox("code?")
Range("D1").Value = Now()
Else
FoundCell.Activate
' If PrevCell.Address = FoundCell.Address Then
' MsgBox "there's only one!"
' End If
ActiveCell.Offset(0, 1).Select
timestamp = Format(Now(), "dd-mmm-yy hh:mm")
ActiveCell = timestamp
ActiveCell = Now()
ActiveCell.Offset(0, 2).Select
ActiveCell = "T141000"
ActiveCell.Offset(0, 1).Select
Set PrevCell = FoundCell
End If
End Sub
The problem here lies in your if statement - you are always storing the newly entered codes in cells C1 and the date in D1. You need to dynamically work out the next available row number and use that instead. Try something like this:
Public Sub DataInput()
...
If FoundCell Is Nothing Then
MsgBox SearchTarget & " was not found."
Dim nextFreeRow As Integer
nextFreeRow = Range("C" & Rows.Count).End(xlUp).Row + 1
Range("C" & nextFreeRow).Value = InputBox("code?")
Range("D" & nextFreeRow).Value = Now()
Else
...
End If
...
End Sub
Related
I created a macro that fills the missing Data with specific Data from another sheet , the codes works perfectly in copying pasting data from excel of the client and prepare the data needed to start the work but the only problem here below
Code:
With Worksheets("Feuil2")
' reference "target" sheet (change "Target" to our actual target sheet name)
With .Range("B1:B" & .Cells(.Rows.Count, 1).End(xlUp).Row) 'reference
its column B range from row 1 down to last not empty one
If WorksheetFunction.CountBlank(.Cells) > 0 Then
' if any blank cell in referenced range. this check to avoid error thrown by subsequent
statament
.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=index(GDC!" & rng.Offset(, 1).Address(, , xlR1C1) & ",match(RC[-1],GDC!" & rng.Address(, , xlR1C1) & ",0))" 'fill blank cells with a lookup (well, sort of) formula
.Value = .Value 'get rid of formulas and leave values only
Cells.Select
End If
End With
End With
This code works perfectly in matching and filling data but when for e.g find a duplicated value it copy only the first value not the second one
See the image below to better understand the main problem :
As you can see in the image The problem that in column A i may have data repeated twice like this value P20845 which in column F it is repeated one with the name of Ghaith and the other with the name of sirine but as you can see in the column A it is just with the name also of Ghaith and there is no name of sirine
Anyidea or better solution in solving this and getting all the needed DATA? .
Best Regards
POLOS
Or use a dictionary
Option Explicit
Public Sub AddValues()
Application.ScreenUpdating = False
Dim wb As Workbook, wsSource As Worksheet, wsTarget As Worksheet, masterDict As Object, arr() As Variant, i As Long, rng As Range
Set wb = ThisWorkbook
Set wsSource = wb.Worksheets("Feuil1")
Set wsTarget = wb.Worksheets("Feuil2")
Set masterDict = CreateObject("Scripting.Dictionary")
With wsSource
arr = Intersect(.Columns("A:B"), .UsedRange)
For i = 1 To UBound(arr, 1)
If Not masterDict.exists(arr(i, 1)) Then masterDict.Add arr(i, 1), GetAllMatches(arr(i, 1), arr(i, 2), wsSource)
Next i
End With
With wsTarget
For Each rng In Intersect(.Columns("A"), .UsedRange)
On Error Resume Next
rng.Offset(, 1) = masterDict(rng.Value)
On Error GoTo 0
Next rng
End With
Application.ScreenUpdating = True
End Sub
Public Function GetAllMatches(ByVal findString As String, ByVal dupString As String, ByVal searchRng As Worksheet) As String
Dim foundCell As Range
Dim concatenatedString As String
concatenatedString = vbNullString
With Intersect(searchRng.Columns(1), searchRng.UsedRange)
Set foundCell = .Find(findString)
If foundCell Is Nothing Then Exit Function
If Not foundCell Is Nothing Then concatenatedString = foundCell.Offset(, 1)
Dim currMatch As Long
currMatch = 0
For currMatch = 1 To WorksheetFunction.CountIf(.Cells, findString)
Set foundCell = .Find(What:=findString, After:=foundCell, _
LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not foundCell Is Nothing And InStr(1, dupString, concatenatedString) = 0 Then
concatenatedString = concatenatedString & "/" & foundCell.Offset(, 1)
Else
concatenatedString = foundCell.Offset(, 1)
End If
Next currMatch
End With
GetAllMatches = concatenatedString
End Function
Output in Feuil2
Maybe something like this instead?
Sub Test()
Dim i As Long, myrow As Long, lastrow As Long
Dim sht1 As Worksheet, sht2 As Worksheet
Set sht1 = ThisWorkbook.Worksheets("Sheet1")
Set sht2 = ThisWorkbook.Worksheets("Sheet2")
lastrow = 1
For i = 1 To 7
If Application.WorksheetFunction.CountIf(sht1.Range("A:A"), sht2.Range("F" & i).Value) = 0 Then
If i = 1 Then
lastrow = 1
Else
lastrow = sht1.Cells(sht1.Rows.Count, "A").End(xlUp).Row + 1
End If
sht1.Range("A" & lastrow).Value = sht2.Range("F" & i).Value
sht1.Range("B" & lastrow).Value = sht2.Range("G" & i).Value
Else
sht1.Range("B" & sht1.Columns("A:A").Find(What:=sht2.Range("F" & i).Value).Row).Value = sht1.Range("B" & sht1.Columns("A:A").Find(What:=sht2.Range("F" & i).Value).Row).Value & "/" & sht2.Range("G" & i).Value
End If
Next i
End Sub
I would like to call sub-routine to remove rows that contain a certain value in a cell from my column colCell. So we are creating a string that contains '' if it cannot identify any values on another sheet to create the string from.
aCell.Value = Replace(aCell.Value, Split(aCell.Value, ",")(1), "'" & Sheet5.Cells(colCell.Row, 2) & "'")
DeleteRows (colCell)
I thought I could call the sub-routine above and pass in the column variable?
Main sub-routine:
Sub Main()
Set wDFS = ThisWorkbook.Sheets("Data")
Set colCell = wDFS.Rows("1:1").Find(what:="New query", after:=wDFS.Cells(1, 1), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not colCell Is Nothing Then
Set rng = wDFS.Range(wDFS.Cells(2, colCell.Column), wDFS.Cells(wDFS.UsedRange.Rows.Count, colCell.Column))
For Each aCell In rng
Set colCell = Sheet5.Range("A1:A" & Sheet5.UsedRange.Rows.Count).Find(what:=Replace(Split(aCell.Value, ",")(1), "'", ""), after:=wDFS.Cells(1, 1), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not colCell Is Nothing Then
aCell.Value = Replace(aCell.Value, Split(aCell.Value, ",")(1), "'" & Sheet5.Cells(colCell.Row, 2) & "'")
DeleteRows (colCell)
Else
With Sheet5.Range("A" & Sheet5.Range("A" & Rows.Count).End(xlUp).Row + 1)
.Value = Replace(Split(aCell.Value, ",")(1), "'", "")
.Interior.Color = 255
End With
End If
Next aCell
Else
MsgBox "No new query column found in " & wDFS.Name & " sheet"
End If
End Sub
Sub-routine for deleting rows:
Sub DeleteRows(colCell)
Dim c As Range
Dim SrchRng
Set SrchRng = ActiveSheet.Range("Data", ActiveSheet.Range(colCell).End(xlUp))
Do
Set c = SrchRng.Find("''", LookIn:=xlValues)
If Not c Is Nothing Then c.EntireRow.Delete
Loop While Not c Is Nothing
End Sub
In th debug, it says there is an issue with the following line:
Set SrchRng = ActiveSheet.Range("DataFeedSheet", ActiveSheet.Range(colCell).End(xlUp))
I assume it is something related to the range I have specified.
How do you do this?
Thanks in advance!
Sub DeleteRow4()
Dim rng As Range, cell_search As Range, del As Range
Set rng = Intersect(Range("Data"), ActiveSheet.UsedRange)
For Each cell_search In rng
If (cell_search.Value) = "9999" Then
'Your specific cell value goes here
If del Is Nothing Then
Set del = cell_search
Else: Set del = Union(del, cell_search)
End If
End If
Next cell_search
On Error Resume Next
del.EntireRow.Delete
End Sub
I have a macro that until now was used just to search one cell from column F but now I must search for all the cell in column F. If value from F is found in range N:AN, offset(f,0,1) must have the cell value (found row , column AI).
Sub find()
Dim FindString As String
Dim Rng As Range
FindString = Sheets("Sheet1").Range("f48").Value
If Trim(FindString) <> "" Then
With Sheets("Sheet1").Range("n:an")
Set Rng = .find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Sheets("Sheet1").Range("f48").Offset(0, 1).Value = Rng.Offset(0, 21).Value
Else
Sheets("Sheet1").Range("f48").Offset(0, 1).Value = "Nothing found"
End If
End With
End If
End Sub
Perhaps this, if I understand correctly (it does assume the value in F will only be found once at most).
Sub find()
Dim Rng As Range
Dim r As Range
With Sheets("Sheet1")
For Each r In .Range("F1", .Range("F" & .Rows.Count).End(xlUp))
If Trim(r) <> vbNullString Then
With .Range("n:an")
Set Rng = .find(What:=r.Value, _
LookAt:=xlWhole, _
MatchCase:=False)
If Not Rng Is Nothing Then
r.Offset(0, 1).Value = .Cells(Rng.Row, "AI").Value
'Else
' Sheets("Sheet1").Range("f48").Offset(0, 1).Value = "Nothing found"
End If
End With
End If
Next r
End With
End Sub
See if this is helpful. Its a bit of a change but I think it may be cleaner :)
Of course you need to adjust it for your offset criteria once you "find" a match in the N:NA range
Sub Dougsloop()
Dim rCell As Range
Dim rRng As Range
Dim wsO As Worksheet
Dim aRR As Variant
Set wsO = ThisWorkbook.Sheets("Sheet1")
aRR = wsO.UsedRange.Columns("N:NA")
Set rRng = ThisWorkbook.Sheets("Sheet1").Range("F1:F500")
For Each rCell In rRng.Cells
If Trim(rCell.Value) <> vbNullString Then
thisValue = rCell.Value
If IsError(Application.Match(aRR, thisValue, 0)) = True Then
'Generic Eror Handling
ElseIf IsError(Application.Match(aRR, thisValue, 0)) = False Then
'Stuff you do when you find the match
rCell.Offset(0, 1).Value = "found it"
End If
End If
Next rCell
End Sub
I am searching for a column in vba that has a certain header and then when I find that I want to search all the rows in that column and replace all the X's with 1's. I have all the code written but for some reason its not allowing the line shown below:
r2 = Range(i, i).EntireColumn.Rows.Count
Sub PA_Change()
Dim i As Long, r As Range, rRow As Range, r2 As Long
Set r = Range("A1")
Set rRow = r.EntireRow
For i = 1 To rRow.Columns.Count
If Cells(1, i) = PA_REQUIRED Then
r2 = Range(i, i).EntireColumn.Rows.Count
For j = 1 To r2
If Cells(j, i).Value = "X" Then
Cells(j, i).Value = "1"
End If
Next j
End If
Next i
End Sub
Try replacing all your code with this and let us know if that works:
*replace the "boo" in searchFor with the actual header name / PA_REQUIRED
Sub PA_Change()
Dim searchFor As String
searchFor = "boo"
Dim grabColumn As Range
Set grabColumn = Rows("1:1").Find(What:=searchFor, _
After:=Range("A1"), LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=False, _
SearchFormat:=False)
If Not grabColumn Is Nothing Then
Dim entireColumn As Range
Set entireColumn = Range(grabColumn.Address & ":" & Split(grabColumn.Address, "$")(1) & Range(Split(grabColumn.Address, "$")(1) & Rows.Count).End(xlUp).Row)
Dim cell As Range
For Each cell In entireColumn
If UCase(cell) = "X" Then
cell = "1"
End If
Next
Else
Exit Sub ' not found
End If
End Sub
I want to amend the code below
I want the findwhat to pick text from a range ("a1:20")-which contains the list of text i want to look for
If it finds the text in the description in B, i want it to return the text it found e.g jo IN range c beside its description
Thanks
Option Explicit
Sub x()
Dim FindWhat, rngCell As Range, i As Integer
FindWhat = Array("Jo", "oa", "of", "koo")
For i = 0 To 3
For Each rngCell In Range("B2", Range("B" & Rows.Count).End(xlUp))
If InStr(rngCell, FindWhat(i)) <> 0 Then
rngCell.Offset(0, 1) = rngCell
rngCell.Offset(, 1).Resize(, 2).Copy
End If
Next rngCell
Next i
End Sub
Try this:
Option Explicit
Sub x()
Dim findRng As Range, _
targetRng As Range, _
findCell As Range, _
found As Range
Dim i As Integer
Dim firstFound As String, _
columnName As String
columnName = "B"
Set findRng = Range("A1:A20")
For Each findCell In findRng
Set targetRng = Range(columnName & "2", Range(columnName & Rows.Count).End(xlUp))
With targetRng
Set found = .Find(findCell.Value, LookIn:=xlValues, lookat:=xlPart)
If Not found Is Nothing Then
firstFound = found.Address
Do
found.Offset(0, 1).Value = found.Offset(0, 1).Value & findCell.Value & ", "
Set found = .FindNext(found)
Loop While Not found Is Nothing And found.Address <> firstFound
End If
End With
Next findCell
End Sub
Note that unless what you're doing is a little more complex than this, you can achieve this result using cell formulae. Read the help on the Index, Match and VLookup functions to see how to achieve this.