how to select a section of ranges - vba

To assign xx in the AP column, i have to check some fields that they must be filled before the xx assignment
i tried to assign some columns to a variable and i did the control to that variable, but it seems like it doesn't work
I got an error on this line
Set MaPlage = Columns("A:R" & "W:E").Rows(i)
this is my code :
Sub Decision()
Dim cell As Range
Dim i As Integer
Dim j As Integer
Dim x As Integer
Dim y As Integer
Dim z As Integer
Dim u As Integer
Dim t As Integer
Dim l As Integer
Dim p As Integer
Set MaPlage = Columns("A:R" & "W:E").Rows(i)
For i = 2 To ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
If CStr(ActiveSheet.Cells(i, 31).Value) = "Completed - Appointment made / Complété - Nomination faite" And (ActiveSheet.MaPlage.Value) = "<>" Then
If CStr(ActiveSheet.Cells(i, 14).Value) = "AEP" _
Or CStr(ActiveSheet.Cells(i, 14).Value) = "CMC_REV" _
Or CStr(ActiveSheet.Cells(i, 14).Value) = "CMC_APT" _
Or CStr(ActiveSheet.Cells(i, 14).Value) = "CS_TPD" _
Or CStr(ActiveSheet.Cells(i, 14).Value) = "DM_ID" Then
ActiveSheet.Cells(i, 42).Value = "XX"
End If
End If
Next i

Combining all the comments try this:
For i = 2 To ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
Set maplage = Range("A" & i & ":H" & i & ",J" & i & ":R" & i & ",W" & i & ":Z" & i & ",AA" & i & ":AO" & i)
If UCase(Left(ActiveSheet.Cells(i, 31).Value), 3) = "COM" _
And WorksheetFunction.Countif(MaPlage,"") = 0 Then
Select Case UCase(Left(ActiveSheet.Cells(i, 14).Value), 3)
Case "AEP", "CMC", "CS_", "DM_"
ActiveSheet.Cells(i, 42).Value = "XX"
End Select
End If
Next i

Related

Loops and "i" - Correctly inputting "i"

I have no idea how to add in the "i" to the following code. I've gone through previous questions, but I can't get this to run properly. Ideas? Starting after "ELSE", I have no idea how to add in the "i". Any help would be appreciated.
For i = 2 To myLastRow
Set mycell = myWorksheet.Range("AK" & i)
Set mycell2 = myWorksheet.Range("AD" & i)
Else
**mycell.Offset(, 2).Formula = "==IF(ABS(AJ" & i & " - AL" & i & ") <= AL" & i & "*0.1, TRUE, FALSE) "**
Dim i As Integer
Dim mylastrow As Integer
Dim myworksheet As Worksheet
Dim mycell As Range
Dim mycell2 As Range
Set myworksheet = Sheet1
mylastrow = 10
For i = 2 To mylastrow
Cells(i, "AK").Offset(, 2).Formula = "=IF(ABS(AJ" & i & " - AL" & i & ") <= AL" & i & "*0.1, TRUE, FALSE) "
' Cells(i, "AD").Value
Next i
Are you trying to do something like this? The cells property works perfect for thse types of loops.

searching in VBA with a certian number format

I am trying to create a sub that uses a chunk of a code as a search term and finds it in a different row. I am trying to search for a four digit code such as 0032 but no matter what I try, it searches for 32 and ends up finding sections such as 1132, 1321, and 3211,which I don't want. This is what I have right now to address the problem.
For i = 1 To frng.Count
crng(i, 1).Value = Application.WorksheetFunction.CountIf(mfrng, cfrng(i, 1).Value)
Next i
'puts the number of times it appears next to the filtered version of it
'to find the row number
'use numbers from cfrng to search in mcode range and find rownumbers. Then add one to the rownumber and use it to copy and paste the other columns. Organize by lcode + 40000
Dim wrrow As Long
Dim wdrow As Long
Dim flist As Range
rangevalue = ("R2:R" & flastrow)
Set flist = Range(rangevalue)
Dim nlist As Range
rangevalue = ("S2:S" & flastrow)
Set nlist = Range(rangevalue)
Dim Search As Variant
Dim j As Integer
Dim n As Integer
Dim found As Object
For j = 1 To flist.Count
Search = flist(j, 1)
n = nlist(j, 1)
Set found = mfrng.Find(What:=Search, LookIn:=xlValues, lookat:=xlPart, searchformat:=True)
Dim s As Integer
For s = 1 To n
If s = 1 Then GoTo First Else GoTo Second
First:
wrrow = found.Row
wdrow = (wrrow + 1)
wd.Activate
Dim high As Range
rangevalue = ("V" & wdrow & ", AA" & wdrow & ", D" & wdrow & ", E" & wdrow & ", L" & wdrow & ", M" & wdrow & ", U" & wdrow)
Set high = Range(rangevalue)
high.Select
Selection.Copy
wr.Activate
Dim r As Integer
Dim v As Integer
r = wr.Cells(wr.Rows.Count, "B").End(xlUp).Row
v = (r + 1)
wr.Range("B" & v).Select
ActiveSheet.Paste
wr.Range("A" & v).Value = j
GoTo Third
Second:
Set found = mfrng.FindNext(found)
wrrow = found.Row
wdrow = (wrrow + 1)
wd.Activate
rangevalue = ("V" & wdrow & ",AA" & wdrow & ",D" & wdrow & ",E" & wdrow & ",L" & wdrow & ",M" & wdrow & ",U" & wdrow)
Set high = Range(rangevalue)
high.Select
Selection.Copy
r = wr.Cells(wr.Rows.Count, "B").End(xlUp).Row
v = (r + 1)
wr.Activate
Range("B" & v).Select
ActiveSheet.Paste
wr.Range("A" & v).Value = j
Third:
Next s
Next j
The value in flist is displayed as 0032 but when I try and use the search it represents 32, not 0032. When I try the number format it returns an object required error.
I have set the search to a variant.
Some examples of what I am comparing the search to are 0032, which is the one I want, but also 2132, 3225, etc. I only want it to find the rows with 0032.
I have a list of search terms which is what the j variable changes. I also have a number of the times a certain variable appears which is what the nlist is.
From everyone's advice I was able to figure it out.
This is what my final code looks like.
Dim wrrow As Long
Dim wdrow As Long
Dim flist As Range
rangevalue = ("R2:R" & flastrow)
Set flist = Range(rangevalue)
Dim nlist As Range
rangevalue = ("S2:S" & flastrow)
Set nlist = Range(rangevalue)
Dim Search As String
Dim codenum As Integer
Dim seriesnum As Integer
Dim found As Range
Dim current As Integer
Dim high As Range
Dim blastcell As Integer
Dim bemptycell As Integer
Dim findrng As Range
rangevalue = ("O1:O" & rlastrow)
Set findrng = Range(rangevalue)
For codenum = 1 To flist.Count
Search = flist(codenum, 1)
seriesnum = nlist(codenum, 1)
For current = 1 To seriesnum
If current = 1 Then
Set found = findrng.Find(What:=Search, LookAt:=xlWhole, searchformat:=True)
wrrow = found.Row
wdrow = (wrrow + 1)
wd.Activate
rangevalue = ("V" & wdrow & ", AA" & wdrow & ", D" & wdrow & ", E" & wdrow & ", L" & wdrow & ", M" & wdrow & ", U" & wdrow)
Set high = Range(rangevalue)
high.Select
Selection.Copy
wr.Activate
blastcell = wr.Cells(wr.Rows.Count, "B").End(xlUp).Row
bemptycell = (blastcell + 1)
wr.Range("B" & bemptycell).Select
ActiveSheet.Paste
wr.Range("A" & bemptycell).Value = codenum
GoTo Next_item
End If
Set found = mfrng.FindNext(found)
wrrow = found.Row
wdrow = (wrrow + 1)
wd.Activate
rangevalue = ("V" & wdrow & ",AA" & wdrow & ",D" & wdrow & ",E" & wdrow & ",L" & wdrow & ",M" & wdrow & ",U" & wdrow)
Set high = Range(rangevalue)
high.Select
Selection.Copy
wr.Activate
blastcell = wr.Cells(wr.Rows.Count, "B").End(xlUp).Row
bemptycell = (blastcell + 1)
wr.Range("B" & bemptycell).Select
ActiveSheet.Paste
wr.Range("A" & bemptycell).Value = codenum
Next_item:
Next current
Next codenum
It now does exactly what I wanted it to and only returns the cells with a code exactly matching the codenum.

For each loop to go to next row in iteration once value found in range

All,
I have the below code which iterates through columns and rows to see IF the statement is true. It seems to be running through the whole code bringing back duplicate rows. I would like this code to go to the next row once a value has been found.
I'm unsure how to adapt this code but I imagine the issue lies with the general for each loop I have set up any advise on how to fix this would be much appreciated.
Dim LR As Long
LR = Workbooks(trackerName).Sheets("Results").Range("A1048576").End(xlUp).Row
Dim LRC As Long
LRC = Workbooks(trackerName).Sheets("Columnsforbox").Range("A1048576").End(xlUp).Row + 1
For Each c In Workbooks(trackerName).Sheets("results").Range("A4:K" & LR)
If c.Value = UserName Or c.Value = UserId Then
Worksheets("Columnsforbox").Range("A" & LRC) = Worksheets("Results").Range("E" & c.Row)
Worksheets("Columnsforbox").Range("B" & LRC) = Worksheets("Results").Range("D" & c.Row)
Worksheets("Columnsforbox").Range("C" & LRC) = Worksheets("Results").Range("A" & c.Row)
Worksheets("Columnsforbox").Range("D" & LRC) = Worksheets("Results").Range("B" & c.Row)
Worksheets("Columnsforbox").Range("E" & LRC) = Worksheets("Results").Range("C" & c.Row)
LRC = LRC + 1
End If
Next c
Basicly the same, but now we loop through array:
Dim myArr(), i as Long, j as Long
Dim LR As Long
LR = Workbooks(trackerName).Sheets("Results").Range("A1048576").End(xlUp).Row
Dim LRC As Long
LRC = Workbooks(trackerName).Sheets("Columnsforbox").Range("A1048576").End(xlUp).Row + 1
myArr = Range("A4:K" & LR).Value
For i = LBound(myArr,1) To Ubound(myArr,1)
For j = LBound(myArr,2) To Ubound(myArr,2)
If myArr(i,j) = UserName Or myArr(i,j) = UserId Then
Worksheets("Columnsforbox").Range("A" & LRC) = Worksheets("Results").Range("E" & i)
Worksheets("Columnsforbox").Range("B" & LRC) = Worksheets("Results").Range("D" & i)
Worksheets("Columnsforbox").Range("C" & LRC) = Worksheets("Results").Range("A" & i)
Worksheets("Columnsforbox").Range("D" & LRC) = Worksheets("Results").Range("B" & i)
Worksheets("Columnsforbox").Range("E" & LRC) = Worksheets("Results").Range("C" & i)
LRC = LRC + 1
Exit For
End If
Next j
Next i
Well, you got an idea.
Another solution without using loop.
Sub Demo()
Dim rngUserName As Range, rngUserId As Range
Dim LR As Long, LRC As Long, rowIndex As Long
Dim srcSht As Worksheet, destSht As Worksheet
Set srcSht = Workbooks(trackerName).Sheets("Results") 'this is source sheet
Set destSht = Workbooks(trackerName).Sheets("Columnsforbox") 'this is destination sheet
LR = srcSht.Cells(srcSht.Rows.Count, "A").End(xlUp).Row 'get last row using column A
LRC = destSht.Cells(destSht.Rows.Count, "A").End(xlUp).Row 'get last row using column A
Set rngUserName = Range("A4:K" & LR).Find(UserName, after:=Cells(4, 1), searchdirection:=xlPrevious) 'find user name
Set rngUserId = Range("A4:K" & LR).Find(UserId, after:=Cells(4, 1), searchdirection:=xlPrevious) 'find user id
If Not rngUserName Is Nothing And Not rngUserId Is Nothing Then 'if both user name & user id are found
rowIndex = Application.Max(rngUserName.Row, rngUserId.Row)
ElseIf Not rngUserName Is Nothing Then 'if only user name found
rowIndex = rngUserName.Row
ElseIf Not Not rngUserId Is Nothing Then 'if only user id found
rowIndex = rngUserId.Row
End If
MsgBox rowIndex
destSht.Range("A" & LRC) = srcSht.Range("E" & rowIndex)
destSht.Range("B" & LRC) = srcSht.Range("D" & rowIndex)
destSht.Range("C" & LRC) = srcSht.Range("A" & rowIndex)
destSht.Range("D" & LRC) = srcSht.Range("B" & rowIndex)
destSht.Range("E" & LRC) = srcSht.Range("C" & rowIndex)
End Sub

Find matching cell with different strings inside one cell

My goal of my macro:
I have 2 sheets, sheet1 master report and sheet2 import Input.
In column A of both sheets I have several strings in one cell.
I would like to see if there is a match and if there is the match the row from sheet2 (from column B) will be copied and paste in the row corresponding in sheet1.
This part of my code is done.
But now it starts to be tricky: If there is new string in the same cell as the matching string so I would like to add them as well in the cell of the column A sheet1.
For instance:
Sheet1 Column A Cell34:
MDM-9086
Sheet2 Column A Cell1:
MDM-9086,MDM-12345
After the macro it would be like this:
Sheet1 Column A cell34:
MDM-9086,MDM-12345
If there is no match between column A of both sheets so I would like to copy the entire row of the sheet2 and past it in the last free row of the sheet1.
See my code:
Sub MDMNumbers()
Dim LastRw1 As Long, LastRw2 As Long, NxtRw As Long
Dim I As Integer
Dim m As Range
Dim Tb
LastRw1 = Sheets(1).Range("A" & Rows.Count).End(xlUp).Row
LastRw2 = Sheets(2).Range("A" & Rows.Count).End(xlUp).Row
With Worksheets(2)
LastRw2 = .Range("A" & Rows.Count).End(xlUp).Row
For NxtRw = 2 To LastRw2
Tb = Split(.Range("A" & NxtRw), ",")
For I = 0 To UBound(Tb)
With Sheets(1).Range("A2:A" & LastRw1)
Set m = .Find(Trim(Tb(I)), LookAt:=xlPart)
If Not m Is Nothing Then
Sheets(2).Range("B" & NxtRw & ":Q" & NxtRw).Copy _
Sheets(1).Range("B" & m.Row)
Set m = Nothing
End If
End With
Next I
Next NxtRw
End With
End Sub
Example:
Sheet 1, Column A (start row 2)
MDM-123,MDM-27827
MDM-1791728,MDM-124
MDM-125
MDM-126,MDM-28920
MDM-127,MDM-1008
""
Sheet 2, Column A (start row 2)
MDM-123,MDM-27272
MDM-124
MDM-125,MDM-1289
MDM-126
MDM-1008
MDM-127
MDM-172891
Result on Sheet 1, Column A (start row 2):
MDM-123,MDM-27827,MDM-27272
MDM-124,MDM-1791728
MDM-125,MDM-1289
MDM-126,MDM-28920
MDM-127,MDM-1008
MDM-1008
MDM-172891
For your # 2.
Option Explicit
Public Sub MDMNumbers()
Dim LastRw1 As Long, LastRw2 As Long, NxtRw As Long, rng1 As Range, rng2 As Range
Dim i As Long, m As Range, tb() As String, celVal As String, notFound As Boolean
Dim additions1 As String, additions2 As String
LastRw1 = Worksheets(1).Range("A" & Worksheets(1).Rows.Count).End(xlUp).Row + 1
LastRw2 = Worksheets(2).Range("A" & Worksheets(2).Rows.Count).End(xlUp).Row
notFound = True
For NxtRw = 2 To LastRw2
celVal = Worksheets(2).Range("A" & NxtRw).Value2
If Len(celVal) > 0 Then
tb = Split(celVal, ",")
For i = 0 To UBound(tb)
Set m = Worksheets(1).Columns(1).Find(Trim(tb(i)), LookAt:=xlPart)
If Not m Is Nothing And notFound Then
Set rng1 = Worksheets(2).Range("B" & NxtRw & ":Q" & NxtRw)
Set rng2 = Worksheets(1).Range("B" & m.Row & ":Q" & m.Row)
rng1.Copy rng2
With Worksheets(2).Range("A" & NxtRw)
additions1 = Replace(.Value2, "," & tb(i), vbNullString)
additions1 = Replace(additions1, tb(i) & ",", vbNullString)
additions1 = Replace(additions1, tb(i), vbNullString)
End With
With Worksheets(1).Range("A" & m.Row)
additions2 = Replace(.Value2, "," & tb(i), vbNullString)
additions2 = Replace(additions2, tb(i) & ",", vbNullString)
additions2 = Replace(additions2, tb(i), vbNullString)
If Len(additions2) > 0 Then
If Len(additions1) > 0 Then
.Value2 = tb(i) & "," & additions2 & "," & additions1
Else
.Value2 = tb(i) & "," & additions2
End If
Else
.Value2 = tb(i) & "," & additions1
End If
End With
Set m = Nothing
notFound = False
End If
Next
If notFound Then
Set rng1 = Worksheets(2).Range("A" & NxtRw & ":Q" & NxtRw)
Set rng2 = Worksheets(1).Range("A" & LastRw1 & ":Q" & LastRw1)
rng1.Copy rng2
LastRw1 = LastRw1 + 1
End If
notFound = True
End If
Next
End Sub
It should work as expected now
Test data and result:
Why don't you copy the whole row from sheet2 to sheet1 like
For NxtRw = 2 To LastRw2
...
Sheets(2).Range("A" & NxtRw & ":Q" & NxtRw).Copy _
Sheets(1).Range("A" & m.Row)
...
Next NxtRw
? (The rest of the loop should stay the same.)

How to increase only last digit of a serial number string in Excel VBA?

I'm new to vba and trying to write a barcode scanner algorithm. It works fine right now but I want to keep serial numbers in my exel table and their structure has to be like "A151000". I want with each barcode entered a cell with an inputbox also be assigned to a serial number. for example when a new entry(Barcode) written in column C I want in column B serial numbers last digit increased by 1 and stored in that cell automatically.
Right now I can drag the cell from corner and exel increases the last digit. How can I trigger this with new entries automatically? Thanks in advance.
A151000
A151001
A151002
...
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
Dim buttonclick As Boolean
V = True
If PrevCell Is Nothing Then
myRow = Selection.Row
Set PrevCell = Range("C" & myRow)
End If
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
Dim Eingabezahl As String
Do While Eingabezahl! = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Range("C" & Range("C" & Rows.Count).End(xlUp).Row + 1) = Eingabezahl
Range("D" & Range("D" & Rows.Count).End(xlUp).Row + 1) = Now()
Range("E" & Range("E" & Rows.Count).End(xlUp).Row + 1) = "VALID"
Loop
End Sub
TO use the Autofill function and not change your original code you could just add in the autofill in your sub:
Dim Eingabezahl As String
Dim rngLastBCell As Range
Do While Eingabezahl = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Set rngLastBCell = Range("B" & Rows.Count).End(xlUp)
rngLastBCell.AutoFill Destination:=Range(rngLastBCell, rngLastBCell.Offset(1)), Type:=xlFillDefault
Range("C" & Range("C" & Rows.Count).End(xlUp).Row + 1) = Eingabezahl
Range("D" & Range("D" & Rows.Count).End(xlUp).Row + 1) = Now()
Range("E" & Range("E" & Rows.Count).End(xlUp).Row + 1) = "VALID"
Loop
Or you could use the following that using the same concept (an autofill) but condenses al of your calls to the worksheet into a single line:
Dim Eingabezahl As String
Dim rngLastBCell As Range
Do While Eingabezahl = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Set rngLastBCell = Range("B" & Rows.Count).End(xlUp)
rngLastBCell.AutoFill Destination:=Range(rngLastBCell, rngLastBCell.Offset(1)), Type:=xlFillDefault
rngLastBCell.Offset(1, 1).Resize(, 3) = Array(Eingabezahl, Now(), "VALID")
Loop
Although I would recommend just using appenending the current row to the end of your serial and not making as many calls to the worksheet by using an array:
Dim rngB As Range
Dim Eingabezahl As String
Dim SerialBase As String
SerialBase = "A15100"
Do While Eingabezahl = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Set rngB = Range("B" & Rows.Count).End(xlUp).Offset(1)
rngB.Resize(, 4).Value = Array(SerialBase & rngB.Row, Eingabezahl, Now(), "VALID")
Loop