sheet1 sheet2 sheet3
---------
| |
V V * V-----
123 | A 123 | 456 C | |
* | B 123 | 789 D | |
| C 123 | 345 E | |
^ |
|-----------------
Can I look up 123 from sheet 1 to sheet 2 to return a letter (but that letter must appear in sheet 3 (C), look up the letter that is in sheet 3 and return 456? the problem is there are multiple 123's in sheet 2; I'm only used to dealing with unique numbers. Can it go A is not in sheet 3 so go to next letter until hits C. then lookup value to the left which is 456.
Thanks
Using VBA, inside a Module, write this new function:
Public Function LookFx(Sh1 As Range, Sh2 As Range, Sh3 As Range) As String
Dim BaseVal As String
Dim FoundV As Boolean
Dim SecVal As String
Application.Volatile
BaseVal = Sh1.Value
FoundV = False
For Each xx In Sh2
If xx.Value = BaseVal Then
SecVal = xx.Offset(0, -1).Value
For Each yy In Sh3
If yy.Value = SecVal Then
LookFx = yy.Offset(0, -1).Value
End If
Next
End If
Next
End Function
the value to be add in the function are:
Lets this is your data:
Sheet1:
Sheet2 :
Sheet 3:
The code below will loop through the values in sheet2 if a match is found it will loop through the values in sheet3. If a match is found it will be displayed, else it will c continue its loop in sheet.
Sub main()
Dim intValue As Integer
Dim i As Integer
Dim j As Integer
Dim strChar As String
intValue = Sheet1.Cells(1, 1)
For i = 1 To 3
If intValue = Sheet2.Cells(i, 2) Then
strChar = Sheet2.Cells(i, 1)
For j = 1 To 3
If strChar = Sheet3.Cells(j, 2) Then
MsgBox (Sheet3.Cells(j, 1))
Exit Sub
End If
Next j
End If
Next i
End Sub
Related
I'm looking for some help with a script to filter a specific column containing values from a list on a separate tab.
Basically I have 2 sheets in my workbook:
Sheet 1: contains a dynamic list of values that users need to copy/paste from a different source
Sheet 2: contains a table of data, with column E (5) that needs to be filtered for all values contained in the list on sheet 1. This means exact matches and partial matches.
E.g. User pastes the below list of countries on Sheet 1:
Country
Belgium
Netherlands
France
Column E(5) is filtered for exact and partial matches on Sheet 2:
| Country |
| -------- |
| Belgium |
| Belgium Luxembourg|
| Netherlands |
| France Spain |
| Italy France |
Any ideas how I can get this to work?
Thanks
I have a VBA script that works (see below), but converting it to Apps Script seems impossible as it uses the .exists construct which is not supported by Apps Script.
Sub AutoFltr()
Dim dIn As Object, dOut As Object
Dim a As Variant, b As Variant
Dim i As Long, j As Long
Dim bFound As Boolean
Set dIn = CreateObject("Scripting.Dictionary")
dIn.CompareMode = 1
Set dOut = CreateObject("Scripting.Dictionary")
dOut.CompareMode = 1
With Sheets("Start Here >>")
a = .Range("B17", .Range("B" & Rows.count).End(xlUp)).Value
End With
With Sheets("FA Items")
b = .Range("E2", .Range("E" & Rows.count).End(xlUp)).Value
For i = 1 To UBound(b)
If Not dIn.exists(b(i, 1)) Then
If Not dOut.exists(b(i, 1)) Then
j = 0
bFound = False
Do
j = j + 1
If InStr(1, b(i, 1), a(j, 1), vbTextCompare) > 0 Then
dIn(b(i, 1)) = 1
bFound = True
End If
Loop Until bFound Or j = UBound(a)
If Not bFound Then dOut(b(i, 1)) = 1
End If
End If
Next i
If dIn.count > 0 Then
.Range("A1").CurrentRegion.Autofilter Field:=5, Criteria1:=dIn.Keys, Operator:=xlFilterValues
End If
End With
End Sub
I'm trying to develop a code that brings the nth matching which is selected by the user, I already found a code that execute this but only with only one column
I want to get the third occurence of string "castro" but with the row value a2 which is "19". any suggestions?
below is the code I used to get the second ocurrence but only using one column.
Sub test1()
Dim teste As String
teste = VLOOKUPNTH("prysmian", Range("B1:C22"), 2, 2)
End Sub
Function VLOOKUPNTH(lookup_value, table_array As Range, col_index_num
As Integer, nth_value)
Dim nRow As Long
Dim nVal As Integer
Dim bFound As Boolean
VLOOKUPNTH = "No Match"
With table_array
For nRow = 1 To .Rows.Count
If .Cells(nRow, 1).Value = lookup_value Then
nVal = nVal + 1
End If
If nVal = nth_value Then
VLOOKUPNTH = .Cells(nRow, col_index_num).Text
Exit Function
End If
Next nRow
End With
End Function
the table
A B C
a1 castro 1
a1 castro 3
a1 castro 4
a1 castro 5
a1 castro 6
a1 castro 7
a2 castro 17
a2 castro 18
a2 castro 19
a2 castro 20
a2 castro 21
a2 castro 22
a2 castro 23
I modified your code so that it will check two columns.
1. Changed the range to include column A
2. Changed the column offsets to allow for the added column.
Option Explicit
Sub test1()
Dim teste As String
teste = VLOOKUPNTH("castro", Range("A1:C22"), 3, 3)
Debug.Print "Result: " & teste
End Sub
Function VLOOKUPNTH(lookup_value, table_array As Range, col_index_num As Integer, nth_value As Integer) As String
Dim nRow As Long
Dim nVal As Integer
Dim bFound As Boolean
VLOOKUPNTH = "No Match"
With table_array
For nRow = 1 To .Rows.Count
' Must match both columns to be counted.
If .Cells(nRow, 2).Value = lookup_value And .Cells(nRow, 1).Value = "a2" Then
nVal = nVal + 1
End If
If nVal = nth_value Then
' Now we have found the nth occurence of the lookup value.
VLOOKUPNTH = .Cells(nRow, col_index_num).Text
Exit Function
End If
Next nRow
End With
End Function
I am trying to write a macro that will print out the values in an array depending on conditions in other cells. I have gotten the macro to print out one value in the array, but not the others. The spreadsheet looks like this:
Column 1 | Column 2
___________________
L1 |
L1 |
L2 |
L3 |
L1 |
L5 |
L1 |
The array looks like this: List = Array("Person1", "Person2", "Person3") and what I am trying to do is print Person1, Person2 etc. for every value that says L1 up to that last L1 value. It should look like the example below.
Column 1 | Column 2
___________________
L1 | Person1
L1 | Person2
L2 |
L3 |
L1 | Person3
L5 |
L1 | Person1
The macro below partially works, but it only prints one person, Person3. Any help would be appreciated!
Sub Practice()
Dim i, j, k As Integer
Dim List As Variant
Dim LastRow As Long, CountL As Long
Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets("Sheet1")
List = Array("Person1", "Person2", "Person3")
LastRow = ws.Cells(Rows.Count, "C").End(xlUp).Row - 1
For i = LBound(List) To UBound(List)
For j = 2 To LastRow
If ws.Cells(j, 3).Value = "L1" Then
ws.Cells(j, 4) = List(i)
Else 'Do Nothing
End If
Next j
Next i
End Sub
Note that the "L" values are in Column C and the person names in Column D in the actual spreadsheet, which is why the columns in the macro don't match the columns in the sample data I added here.
Take a look at the below example:
Sub Practice()
Dim ws As Worksheet
Dim List As Variant
Dim LastRow As Long
Dim i As Integer
Dim j As Integer
Set ws = ThisWorkbook.Sheets("Sheet1")
List = Array("Person1", "Person2", "Person3")
LastRow = ws.Cells(ws.Rows.Count, "C").End(xlUp).Row
i = 0
For j = 2 To LastRow
If ws.Cells(j, 3).Value = "L1" Then
ws.Cells(j, 4) = List(i Mod 3)
i = i + 1
End If
Next
End Sub
Your code is currently repeating its actions for each value in the list, and each iteration is assigning a value to every L1 row, and overwriting what was written there in the previous iteration.
You actually need to keep a counter of which value from your array you want to write next:
Sub Practice()
'You should declare the type of each variable, or else they will be Variant
'Dim i, j, k As Integer
Dim i As Integer, j As Integer, k As Integer
Dim List As Variant
Dim LastRow As Long, CountL As Long
Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets("Sheet1")
List = Array("Person1", "Person2", "Person3")
'You should fully qualify objects such as Range, Cells and Rows
'LastRow = ws.Cells(Rows.Count, "C").End(xlUp).Row - 1
LastRow = ws.Cells(ws.Rows.Count, "C").End(xlUp).Row '<-- not sure why you subtracted 1
i = LBound(List)
For j = 2 To LastRow
If ws.Cells(j, 3).Value = "L1" Then
ws.Cells(j, 4) = List(i)
i = i + 1
If i > UBound(List) Then
i = LBound(List)
End If
End If
Next j
End Sub
I need help in creating a macro in Excel wherein it grabs a certain cell and copies the entire row x number of times depending on the cell's contents.
To make it clear, let's say I have 2 rows:
| Order # | Item | Qty |
| 30001 | bag | 3 |
| 30002 | pen | 1 |
What I want the macro to do is grab the number under the Qty column and copy the entire row and insert a new line with the exact same contents under it. The number of times it does this depends on the number in the Qty cell. Also, it appends a three digit number in the Order # cell to make it a unique reference point. What the end-result should be:
| Order # | Item | Qty |
| 30001-001 | bag | 1 |
| 30001-002 | bag | 1 |
| 30001-003 | bag | 1 |
| 30002-001 | pen | 1 |
It's hard to explain it here but I hope you get the point. Thanks in advance, gurus!
The following code supports blank lines in the middle of the data.
If Qty = 0, it won't write the Item in the output table.
Please insert at least 1 row of data, because it won't work if there is no data :)
Option Explicit
Sub caller()
' Header at Row 1:
' "A1" = Order
' "B1" = Item
' "C1" = Qty
'
' Input Data starts at Row 2, in "Sheet1"
'
' Output Data starts at Row 2, in "Sheet2"
'
' Sheets must be manually created prior to running this program
Call makeTheThing(2, "Sheet1", "Sheet2")
End Sub
Sub makeTheThing(lStartRow As Long, sSheetSource As String, sSheetDestination As String)
Dim c As Range
Dim rOrder As Range
Dim sOrder() As String
Dim sItem() As String
Dim vQty As Variant
Dim sResult() As String
Dim i As Long
' Reads
With ThisWorkbook.Sheets(sSheetSource)
Set rOrder = .Range(.Cells(lStartRow, 1), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, 1)) ' It will work if there are blank lines in the middle!
i = rOrder.Rows.Count
ReDim sOrder(1 To i)
ReDim sItem(1 To i)
ReDim vQty(1 To i)
i = 1
For Each c In rOrder
sOrder(i) = Trim(c.Text)
sItem(i) = Trim(c.Offset(0, 1).Text)
vQty(i) = c.Offset(0, 2).Value
i = i + 1
Next c
End With
' Processes
sResult = processData(sOrder, sItem, vQty)
' Writes
ThisWorkbook.Sheets(sSheetDestination).Range("A" & lStartRow).Resize(UBound(sResult, 1), UBound(sResult, 2)).Value = sResult
End Sub
Function processData(sOrder() As String, sItem() As String, vQty As Variant) As String()
Dim i As Long
Dim j As Long
Dim k As Long
Dim sResult() As String
j = WorksheetFunction.Sum(vQty) ' That's why vQty had to be Variant!
ReDim sResult(0 To j, 1 To 3)
k = 0
For i = 1 To UBound(sOrder)
For j = 1 To vQty(i)
sResult(k, 1) = sOrder(i) & "-" & Format(j, "000")
sResult(k, 2) = sItem(i)
sResult(k, 3) = "1"
k = k + 1
Next j
Next i
processData = sResult
End Function
I hope it helps you. I had fun making it!
One way: Walk down the qty column inserting as needed then jumping to the next original row;
Sub unwind()
Dim rowCount As Long, cell As Range, order As String, i As Long, r As Long
Set cell = Range("C1")
rowCount = Range("C" & rows.Count).End(xlUp).Row
For i = 1 To rowCount
order = cell.Offset(0, -2).Value
For r = 0 To cell.Value - 1
If (r > 0) Then cell.Offset(r).EntireRow.Insert
cell.Offset(r, 0).Value = 1
cell.Offset(r, -1).Value = cell.Offset(0, -1).Value
cell.Offset(r, -2).Value = order & "-" & Format$(r + 1, "000")
Next
Set cell = cell.Offset(r, 0)
Next
End Sub
i need help with the following excel and what looks like a VBA problem.
The idea here is to generate all the possible combination (without repetition) in each grouping.
INPUT
COLUMN A | COLUMN B
A | 1
X | 1
D | 1
C | 2
E | 2
OUTPUT
COLUMN A | COLUMN B
A | X
A | D
X | D
X | A
D | A
D | X
C | E
E | C
What I managed to do.... how do i let it run only if the data is in the same group.
Option Explicit
Sub Sample()
Dim i As Long, j As Long
Dim CountComb As Long, lastrow As Long
Application.ScreenUpdating = False
CountComb = 0: lastrow = 1
For i = 1 To 10: For j = 1 To 10
Range("G" & lastrow).Value = Range("A" & i).Value & "/" & _
Range("B" & j).Value
lastrow = lastrow + 1
CountComb = CountComb + 1
Next: Next
Application.ScreenUpdating = True
End Sub
see below. Note you need to add the reference Microsoft Scripting Runtime in Tools >> References. Change the Range("A1:A5") to either a dynamic named range or static range and the routine will handle the rest for you. It displays the results starting in G1 but you can also change this / make dynamic as an offset from the data range. Up to you.
Option Explicit
Option Base 1
Dim Data As Dictionary
Sub GetCombinations()
Dim dataObj As Variant
Dim returnData As Variant
Set Data = New Dictionary
Dim i As Double
dataObj = Range("A1:B5").Value2
' Group Data
For i = 1 To UBound(dataObj) Step 1
If (Data.Exists(dataObj(i, 2))) Then
Data(dataObj(i, 2)) = Data(dataObj(i, 2)) & "|" & dataObj(i, 1)
Else
Data.Add dataObj(i, 2), dataObj(i, 1)
End If
Next i
' Extract combinations from groups
returnData = CalculateCombinations().Keys()
Range("G1").Resize(UBound(returnData) + 1, 1) = Application.WorksheetFunction.Transpose(returnData)
End Sub
Private Function CalculateCombinations() As Dictionary
Dim i As Double, j As Double
Dim datum As Variant, pieceInner As Variant, pieceOuter As Variant
Dim Combo As New Dictionary
Dim splitData() As String
For Each datum In Data.Items
splitData = Split(datum, "|")
For Each pieceOuter In splitData
For Each pieceInner In splitData
If (pieceOuter <> pieceInner) Then
If (Not Combo.Exists(pieceOuter & "|" & pieceInner)) Then
Combo.Add pieceOuter & "|" & pieceInner, vbNullString
End If
End If
Next pieceInner
Next pieceOuter
Next datum
Set CalculateCombinations = Combo
End Function