Find a string in Excel and store the column letter in a variable VBA - excel

I would like to find the string "TOTAL" in the first row in each sheet in a workbook and write those column letters in a new sheet.
This is what I got so far. I can find the string and obtain the column letter and show it in a message Box. I tried to store the result in a variable, however I can't figure out how to write the variable back in a already existing sheet.
Sub Find()
Dim rngResult As Range
Dim strToFind As String
Dim addCell As Range
strToFind = "TOTAL"
With Worksheets("Stand.1").UsedRange
Set rngResult = .Find(What:=strToFind, LookAt:=xlPart)
If Not rngResult Is Nothing Then
Dim firstAddress As String, result As String
firstAddress = rngResult.Address
Do
result = result & rngResult.Address & ","
Set rngResult = .FindNext(rngResult)
Loop While rngResult.Address <> firstAddress
output = Mid(result, 2, 1)
MsgBox "Found """ & strToFind & """ in column: " & output
Set addCell = Worksheets("Stand.1").Range(.Address)
End If
End With
End Sub

Adjust Totals (Columns)
The following will loop trough the worksheets, of the workbook containing this code (ThisWorkbook). It will skip the worksheets whose names are in the Exceptions Array.
For each worksheet it will try to find the string "TOTAL" in the first row (header row) and will write the name of the worksheet to the first, and the column number to the second column of Data Array.
At the same time it will calculate the largest column number (MaxColumn).
Using the values collected in Data Array, it will insert empty columns to adjust the Totals Column to the same (max column) in each worksheet, e.g. all worksheets might have the Totals Column in Column Z.
The Code
Option Explicit
Sub adjustTotals()
Const hRow As Long = 1
Const hTitle As String = "TOTAL"
' The Exceptions Array contains the names of the worksheets you want
' to exclude from the adjustment.
Dim Exceptions As Variant
Exceptions = Array("Sheet728") ' add more
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
' Define Data Array ('Data').
Dim Data As Variant
' First column for worksheet name, second for totals column number.
ReDim Data(1 To wb.Worksheets.Count, 1 To 2)
' Additional variables for the upcoming 'For Each Next' loop.
Dim ws As Worksheet ' Current Worksheet
Dim CurrentValue As Variant ' Current Totals Column Number
Dim MaxColumn As Long ' Max Column Number
Dim i As Long ' Data Array Row Counter
' Write worksheet name and total column number to Data Array and
' define Max Column Number.
For Each ws In wb.Worksheets
If UBound(Exceptions) >= LBound(Exceptions) Then
If Not IsError(Application.Match(ws.Name, Exceptions, 0)) Then
GoTo NextWorksheet
End If
End If
CurrentValue = Application.Match(hTitle, ws.Rows(hRow), 0)
If Not IsError(CurrentValue) Then
i = i + 1
Data(i, 1) = ws.Name
Data(i, 2) = CurrentValue
If CurrentValue > MaxColumn Then
MaxColumn = CurrentValue
End If
End If
NextWorksheet:
Next ws
' Insert columns using the values from Data Array..
For i = 1 To i
If Data(i, 2) < MaxColumn Then
wb.Worksheets(Data(i, 1)).Columns(Data(i, 2)) _
.Resize(, MaxColumn - Data(i, 2)).Insert
End If
Next i
' Inform user.
MsgBox "Total columns adjusted.", vbInformation, "Success"
End Sub

Related

Insert numbered cells + row based on cell value

I have managed to insert rows based on cell value for instance if A1 cell is 20, I run the macro, 20 rows appear under A1, those rows are blank right, I need the 20 new cells below A1 to be number 1 to 20 ( the number in A1) let me know if possible.
Cheers Adrien
Try this:
Sub counter()
Dim i as integer
for i = 2 to cells(1, 1) + 1
cells(i, 1) = i - 1
next i
End Sub
Insert an Integer Sequence Below a Cell
A Basic Example For the Active Sheet
Note that this doesn't insert rows, it just writes the integer sequence to the cells below A1.
Sub IntegersBelow()
With Range("A1")
.Resize(.Value).Offset(1).Value _
= .Worksheet.Evaluate("ROW(1:" & CStr(.Value) & ")")
End With
End Sub
Applied to Your Actual Use Case
Adjust the values in the constants section.
Sub InsertIntegersBelow()
' Use constants to change their values in one place instead
' of searching for them in the code (each may be used multiple times).
Const wsName As String = "Sheet1"
Const fRow As Long = 3
Const Col As String = "E"
' Reference the workbook ('wb').
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing the code
' Reference the worksheet ('ws').
Dim ws As Worksheet: Set ws = wb.Worksheets(wsName)
' Calculate the last row ('lRow'),
' the row of the last non-empty cell in the column.
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, Col).End(xlUp).Row
' Validate the last row.
If lRow < fRow Then
MsgBox "No data in column range.", vbInformation
Exit Sub
End If
Dim cCell As Range ' Current Cell
Dim cValue As Variant ' Current Cell Value
Dim r As Long ' Current Row
For r = lRow To fRow Step -1 ' loop backwards
Set cCell = ws.Cells(r, Col) ' reference the current cell...
cValue = cCell.Value ' ... and write its value to a variable
If VarType(cValue) = vbDouble Then ' is a number
cValue = CLng(cValue) ' ensure whole number
If cValue > 0 Then ' greater than 0
' Insert the rows.
cCell.Offset(1).Resize(cValue) _
.EntireRow.Insert xlShiftDown, xlFormatFromLeftOrAbove
With cCell.Offset(1).Resize(cValue)
' Write the values.
.Value = ws.Evaluate("ROW(1:" & cValue & ")")
' Apply formatting.
.ClearFormats
.Font.Bold = True
End With
'Else ' less than or equal to zero; do nothing
End If
'Else ' is not a number
End If
Next r
MsgBox "Rows inserted.", vbInformation
End Sub

How to get first instance of a month and add a new row (Screenshot Included)

See below an image of my Excel Spreadsheet.
What I am trying to accomplish is add 3 blank rows atop of only the first instance each sequential month. So if a new month begins in February (or "2" basically), then 3 blank rows will be automatically added atop of it. I am trying to do this using VBA code. However, my problem runs into how certain functions treat numbers and dates(especially) different from text/strings.
My current VBA code Sub insert() (shown under my image file) uses the LEFT() function on cell A2, but it does not return the value I want, which is "1" or "01" (representing the numerical value of its month). Instead it returns its actual value "44200" etc. - not what I want. I need to find a way to have my VBA code do its job by inserting 3 blank rows atop of each new month. But it can't do that with the LEFT() function. And the MONTH() function won't work in that code either. How do I go about this and alter this code to make it work? Thank you for your help.
Sub insert()
Dim lastRow As Long
Dim done As Boolean
'change A to the longest column (most rows)
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
For i = 1 To lastRow
'change the 1 below to the necessary column (ie, use 4 for column D)
If Left(Cells(i, 1), 2) = "01" Then
Rows(i).insert
done = True
i = i + 1
End If
If done = True Then Exit For
Next
End Sub
Insert Rows on Month Change
On each change of month in cells of column A, it will insert 3 rows above the cell.
It loops from top to bottom and combines the critical cells (or the cells next to them) into a range: first the current cell then the previously combined cells. It alternates between the cells and the cells next to them to not get ranges of multiple cells (Application.Union in GetCombinedRangeReverse: Union([A1], [A2]) = [A1:A2], while Union ([A1], [B2]) = [A1,B2]).
In the end, it loops through the cells of the range to insert rows from bottom to top.
Option Explicit
Sub InsertRows()
Const fRow As Long = 2 ' First Row
Const dtCol As String = "A" ' Date Column
Const RowsToInsert As Long = 3
' Pick one:
' 1. Either (bad, but sometimes necessary)...
'Dim ws As Worksheet: Set ws = ActiveSheet ' could be the wrong one
' 2. ... or better...
'Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
'Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1") ' name
' 3. ... or best:
Dim ws As Worksheet: Set ws = Sheet1 ' code name (not in parentheses)
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, dtCol).End(xlUp).Row
Dim irg As Range ' Insert Range
Dim pMonth As Long ' Previous Month
Dim cMonth As Long ' Current Month
Dim cValue As Variant ' Current Cell Value
Dim cOffset As Long ' Column Offset for GetCombinedRangeReverse
Dim r As Long
For r = fRow To lRow
cValue = ws.Cells(r, dtCol).Value
If IsDate(cValue) Then ' a date
cMonth = Month(cValue)
If cMonth <> pMonth Then ' a different month
pMonth = cMonth
' Changing the column to cover consecutive different months.
cOffset = IIf(cOffset = 0, 1, 0)
Set irg = GetCombinedRangeReverse(irg, _
ws.Cells(r, dtCol).Offset(, cOffset))
Else ' the same month
End If
Else ' not a date
End If
Next r
If irg Is Nothing Then Exit Sub
' This loop is running from bottom to top due to 'GetCombinedRangeReverse'.
Dim iCell As Range
For Each iCell In irg.Cells
iCell.Resize(RowsToInsert).EntireRow.insert
Next iCell
MsgBox "Rows inserted.", vbInformation, "Insert Rows"
End Sub
Function GetCombinedRangeReverse( _
ByVal CombinedRange As Range, _
ByVal AddRange As Range) _
As Range
If CombinedRange Is Nothing Then
Set GetCombinedRangeReverse = AddRange
Else
Set GetCombinedRangeReverse = Union(AddRange, CombinedRange)
End If
End Function

How to match up data from two spreadsheets using specific format

I am wondering if someone can help me figure out how to match up data from two sheets, in a specific format. Here is an example of the data I need matched up, including an example showing expected output.
Note that UniqueToGroup_IDs are unique to only the specific Group_ID listed. As you can see, both of the sample Group_IDs I listed contain a UniqueToGroup_ID value of XSTN, which will return two different result IDs; 2306765 for Group_ID 16453, and 8272773 for Group_ID 8156705.
I can (painfully) do this semi-manually, by a combination of Text To Columns, adding the Group_ID to the UniqueToGroup_ID and NotUniqueToGroup_ID, and VLOOKUP -- but it takes forever and I need to do this often.
I haven't tried to write any VBA yet, because I'm not sure how to approach this problem. I am not terribly experienced with coding.
See example here (Dropbox)
Thank you in advance, for any advice.
Crazy Lookup
Links
Workbook Download how-to-match-up-data-from-two-spreadsheets-using-specific-format_54299649.xls
The Code
Sub CrazyLookup()
Const cSheet1 As String = "Original Data" ' 1st Source Worksheet Name
Const cSheet2 As String = "Data To Match" ' 2nd Source Worksheet Name
Const cSheet3 As String = "Sample Result" ' Target Worksheet Name
Const cFirstR As Long = 2 ' First Row Number
Const cFirstC As Variant = "A" ' First Column Letter/Number
Const cLastC As Variant = "C" ' Source Worksheet's Last Column
Const cNoC As Long = 2 ' Number of Columns of Target Array/Range
Const cDel As String = "|" ' Split/Join Delimiter
Dim vnt1 As Variant ' 1st Source Array
Dim vnt2 As Variant ' 2nd Source Array
Dim vnt3 As Variant ' Target Array
Dim vntU As Variant ' Unique Array
Dim lastR1 As Long ' Last Row Number of 1st Source Range
Dim lastR2 As Long ' Last Row Number of 2nd Source Range
Dim i As Long ' 1st Source Array Row Counter
Dim j As Long ' Unique Array Row Counter
Dim k As Long ' 2nd Source Array Row Counter
Application.ScreenUpdating = False
On Error GoTo ProcedureExit
' Write 1st Source Range to 1st Source Array.
With ThisWorkbook.Worksheets(cSheet1)
lastR1 = .Columns(.Cells(1, cFirstC).Column) _
.Find("*", , -4123, , 2, 2).Row
vnt1 = .Range(.Cells(cFirstR, cFirstC), .Cells(lastR1, cLastC))
End With
' Write 2nd Source Range to 2nd Source Array.
With ThisWorkbook.Worksheets(cSheet2)
lastR2 = .Columns(.Cells(1, cFirstC).Column) _
.Find("*", , -4123, , 2, 2).Row
vnt2 = .Range(.Cells(cFirstR, cFirstC), .Cells(lastR2, cLastC))
End With
' Resize Target Array TO 1st Source Array's rows count and TO
' Number of Columns of Target Array.
ReDim vnt3(1 To UBound(vnt1), 1 To cNoC)
' Write First Source Array's First Column to Target Array's first column.
For i = 1 To UBound(vnt1)
vnt3(i, 1) = vnt1(i, 1)
Next
' Write
For i = 1 To UBound(vnt1) ' Loop through rows of 1st Source Array.
' Split 1st Source Array's row in 3rd column to Unique Array.
vntU = Split(vnt1(i, 3), cDel)
For j = 0 To UBound(vntU) ' Loop through rows of Unique Array.
For k = 1 To UBound(vnt2) ' Loop through rows of 2nd Source Array.
' Match 1st Source Array's row in 2nd column TO 2nd Source
' Array's row in first column AND Unique Array's row TO
' 2nd Source Array's row in 2nd column.
If vnt1(i, 2) = vnt2(k, 1) And vntU(j) = vnt2(k, 2) Then
' Write from 2nd Source Array's row in 3rd column to
' Unique Array's row.
vntU(j) = vnt2(k, 3)
Exit For ' Stop searching.
End If
Next
' Check if match was not found.
If k > UBound(vnt2) Then vntU(j) = "NotFound"
Next
' Join Unique Array's rows to Target Array's row in second column.
vnt3(i, 2) = Join(vntU, cDel)
Next
With ThisWorkbook.Worksheets(cSheet3)
' Clear contents of Target Range columns (excl. Headers).
.Range(.Cells(cFirstR, cFirstC), .Cells(.Rows.Count, _
.Cells(1, cFirstC).Column + cNoC - 1)).ClearContents
' Copy Target Array to Target Range.
.Cells(cFirstR, cFirstC).Resize(UBound(vnt3), UBound(vnt3, 2)) = vnt3
End With
ProcedureExit:
Application.ScreenUpdating = True
End Sub
You can build a two column cross reference with a dictionary.
Option Explicit
Sub ertgyhj()
Dim i As Long, ii As String, gi As Long, ugi As String, nuid As Long, r As String
Dim a As Long, itm As String, tmp As String, arr As Variant, xref As Object, results As Object
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
Set ws1 = Worksheets("original data")
Set ws2 = Worksheets("data to match")
Set ws3 = Worksheets("sample result")
Set xref = CreateObject("scripting.dictionary")
Set results = CreateObject("scripting.dictionary")
'build two column cross reference dictionary
With ws2
For i = 2 To .Cells(.Rows.Count, "A").End(xlUp).Row
itm = Join(Array(.Cells(i, "A").Value2, .Cells(i, "B").Value2), Chr(124))
xref.Item(itm) = .Cells(i, "C").Value2
Next i
End With
'put column header labels into results
results.Item("image_id") = "result"
'collect results
With ws1
'loop through rows
For i = 2 To .Cells(.Rows.Count, "A").End(xlUp).Row
ii = .Cells(i, "A").Value2
gi = .Cells(i, "B").Value2
ugi = .Cells(i, "C").Value2
tmp = vbNullString
arr = Split(ugi, Chr(124))
'loop through UniqueToGroup_ID and find matches
For a = LBound(arr) To UBound(arr)
itm = Join(Array(gi, arr(a)), Chr(124))
If xref.exists(itm) Then
tmp = IIf(CBool(Len(tmp)), tmp & Chr(124), vbNullString) & xref.Item(itm)
End If
Next a
'store concatenated result with image id
results.Item(ii) = tmp
Next i
End With
'post results
With ws3
.Cells(1, "A").Resize(results.Count, 1) = Application.Transpose(results.keys)
.Cells(1, "B").Resize(results.Count, 1) = Application.Transpose(results.items)
End With
End Sub
I built a workbook that I think can solve your problem. Let me know if this helps!
https://www.dropbox.com/s/3h6mja0xtwucbr5/20180121-Matching.xlsm?dl=0

Trim, Copy (insert), Concatenate on selected range

I have a one dimensional column of cells containing text.
I would like to:
strip ".jpg" extension
duplicate each line and insert a copy of the duplicated line beneath it
for each duplicated line (every second line), add a suffix "-Alpha"
apply ".tif" extension to all of the cells
Data looks like this:
0120-052.jpg
0120-053.jpg
0120-054.jpg
0120-055.jpg
0120-056.jpg
I would like to select that range and it appear like so:
0120-052.tif
0120-052-Alpha.tif
0120-053.tif
0120-053-Alpha.tif
0120-054.tif
0120-054-Alpha.tif
0120-055.tif
0120-055-Alpha.tif
0120-056.tif
0120-056-Alpha.tif
I found out how to insert entire rows between the existing data, but I have other data to the left of this data and don't want to have blank rows running across my entire spreadsheet. I did find a way to insert blanks between the existing data but I could not figure out how to instead paste the data when inserting. I fudged something together, but it tried to paste infinitely.
I think I need to put it all into an array and iterate on a step by step basis, but I was unable to figure out how to do that based off of an arbitrary selection.
Sub PasteInsertRowsAfter()
Dim MyCell As Range
For Each MyCell In Selection
If MyCell.Value <> "" Then
MyCell.Copy
MyCell.Offset(1, 0).Insert shift:=xlDown
MyCell.Offset(2, 0).Select
End If
Next MyCell
End Sub
Does this work for you?
Sub PasteInsertRowsAfter()
Dim i As Long
Dim MyCell As Range
Dim Rng As Range
Set Rng = Selection
For i = Rng.Cells.Count To 1 Step -1
Set MyCell = Rng.Cells(i)
MyCell.Copy
MyCell.Offset(1, 0).Insert shift:=xlDown
MyCell.Value = Replace(MyCell.Value, ".jpg", ".tif")
MyCell.Offset(1, 0).Value = Replace(MyCell.Offset(1, 0), ".jpg", "-Alpha.tif")
Next i
End Sub
This sounds like bad data structure to me (inserting rows) so this solution will be based on a column structured table. However, I don't know much else about the data so this could be a wrong assumption on my end.
You could store your values in columns instead like so | Original String | .jpg | -Alpha.tif |
Where Original String is the header for Column A and so on. Your data will be better organized this way since all modifications of original string will be stored on a single row. This structure will allow you to add other info that may be relevant at some point in time (source, date, etc.). You can create pivots with this format and monitor for duplicates easier. You can even store the original string.
Input/Output of macro are below.
This sub is a simple loop that does not take a Slection range.
Sub Alternative()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim MyRange As Range: Set MyRange = ws.Range("A2:A" & ws.Range("A" & ws.Rows.Count).End(xlUp).Row)
Dim MyCell As Range
Application.ScreenUpdating = False
For Each MyCell In MyRange
MyCell.Offset(, 1) = Replace(MyCell, "jpg", "tif")
MyCell.Offset(, 2) = Replace(MyCell, ".jpg", "-Alpha.tif")
Next MyCell
Application.ScreenUpdating = True
End Sub
Here is an option that allows the user to select a range once the macro is launched. Just as the above solution, the macro will output the data in the 2 columns to left of selected range.
Sub Alternative()
Dim MyRange As Range, MyCell As Range
On Error Resume Next 'Allow for Cancel Button
Set MyRange = Application.InputBox("Select Range", Type:=8)
On Error GoTo 0
If Not MyRange Is Nothing Then
Application.ScreenUpdating = False
For Each MyCell In MyRange
MyCell.Offset(, 1) = Replace(MyCell, "jpg", "tif")
MyCell.Offset(, 2) = Replace(MyCell, ".jpg", "-Alpha.tif")
Next MyCell
Application.ScreenUpdating = True
End If
End Sub
Trim160ConcatArrayPaste
Option Explicit
'With Sub ======================================================================
' .Title: Trim160ConcatArrayPaste
' .Author: YMG
'-------------------------------------------------------------------------------
Sub Trim160ConcatArrayPaste()
'Description
' Manipulates data in a selected worksheet range and pastes the result into
' another range (overwriting the former range and more).
'Parameters
' None
'Returns
' Manipulated data in a range.
'
'-- Customize BEGIN --------------------
Const cStr1 As String = ".jpg"
Const cStr2 As String = ".tif"
Const cStr3 As String = "-Alpha.tif"
'If the result should be pasted into another row. Probably useless.
Const loROff As Long = 0 'Row Offset for Array Data
''''''''''''''''''''''''''''''''''''''''
'If the result should be pasted into another column
Const iCOff As Integer = 0 'Column Offset for Array Data
'Remarks:
' I strongly urge you to consider pasting the data into another column e.g.
' the column adjacent to the right of the starting column (Set iCoff = 1).
' If something goes wrong while pasting you will overwrite your initial data
' and you might lose a lot of time getting it back.
' Creating a log file might be considered.
''''''''''''''''''''''''''''''''''''''''
'
'-- Customize END ----------------------
'
Dim oXL As Application 'Exel Application Object
Dim oWb As Workbook 'Workbook Object - ActiveWorkbook
Dim oWs As Worksheet 'Worksheet Object - ActiveSheet
Dim oRng As Range 'Range Object - Range to read from, Range to write to
Dim oCell As Range 'Cell - Range Object - All cells of oRng
Dim arrTCC() As String
Dim lo1 As Long 'Data Entries Counter, Array Entries Counter
Dim strCell As String
Dim strArrRng As String
'
'-------------------------------------------------------------------------------
'Assumptions
' There is a contiguous range (oRng) in the ActiveSheet (oWs) of the
' ActiveWorkbook (oWb) that contains a list of entries in its cells
' (oRng.Cells) to be processed. ('Data' for 'list of entries' in further text)
' The actual range of the Data is selected.
'-------------------------------------------------------------------------------
'
Set oXL = Application
Set oWb = ActiveWorkbook
Set oWs = oWb.ActiveSheet
Set oRng = oXL.Selection
'
'Remarks:
' The Selection Property is a property of the Application object and the
' Window object. Visual Basic doesn't allow ActiveWorkbook.Selection or
' ActiveSheet.Selection.
'
''''''''''''''''''''''''''''''''''''''''
'Task:
' Count the number of Data entries.
'
lo1 = 0 'Data Entries Counter
For Each oCell In oRng.Cells
lo1 = lo1 + 1
Next
'
'Status:
' 'lo1' is the number of Data entries which will be used to determine the
' size of an array in the following code.
'
''''''''''''''''''''''''''''''''''''''''
'Task: Populate an array with the desired results.
'
ReDim arrTCC(1 To lo1 * 2, 1 To 1)
'Explaination:
'"lo1" - Number of list entries.
'" * 2" - Making 2 entries out of each entry.
lo1 = 0 'Array Entries Counter (This is a 1-based array.)
For Each oCell In oRng.Cells
'Clean the text of the Data entries.
strCell = Trim(oCell.Text)
'Remarks:
'Chr(160) which is a non-breaking space (HTML Name: ) is at
'the end of the Data entries. The Trim function doen't clean
'non-breaking spaces.
strCell = Replace(strCell, Chr(160), "")
'Check the last part of the string
If Right(strCell, Len(cStr1)) = cStr1 Then
'Populate array.
lo1 = lo1 + 1
arrTCC(lo1, 1) = Replace(strCell, cStr1, cStr2)
lo1 = lo1 + 1
arrTCC(lo1, 1) = Replace(strCell, cStr1, cStr3)
'If the cell doesn't end with cStr1:
Else 'This should never happen, remember: COUNTIGUOUS.
'An Idea
' lo1 = lo1 + 1
' arrTCC(lo1, 1) = ""
' lo1 = lo1 + 1
' arrTCC(lo1, 1) = ""
MsgBox "You might have selected a wrong range.", vbCritical
Exit Sub
End If
Next
'
' For lo1 = LBound(arrTCC) To UBound(arrTCC)
' Debug.Print arrTCC(lo1, 1)
' Next
' Debug.Print LBound(arrTCC)
' Debug.Print UBound(arrTCC)
'
'Status: The array 'arrTCC' is populated
'
''''''''''''''''''''''''''''''''''''''''
'Task:
' Determine the range where to paste the data from array and paste the
' array into the range.
'
'Calculate the 'Start' Cell Address
strArrRng = oRng.Cells(1 + loROff, 1 + iCOff).Address
'
' Debug.Print strArrRng
'
'Add the ":" (Address Separator) and the Calculated 'End' Cell Address
strArrRng = strArrRng & ":" & _
oRng.Cells(UBound(arrTCC) + loROff, 1 + iCOff).Address
'Paste the Array to the Worksheet
Set oRng = oWs.Range(strArrRng)
'
' Debug.Print strArrRng
' Debug.Print oRng.Address
'
oRng = arrTCC
'
'Status: Done
'
'Remarks:
'Testing the program was done with iCoff = 1 i.e. pasting the array data
'into the column adjacent to the right of the starting column. Since it uses
'overwriting the Data, the Data would always need to be written back for
'further testing.
'Some debugging code has deliberately been commented and left inside the
'program to remind amateurs like myself of debugging importance.
'Some other aspects of this program could be considered like the column
'of the data could be known or unknown so a range, a column or the
'ActiveCell would have or don't have to be selected etc.
'
End Sub
'-------------------------------------------------------------------------------
'With Source Idea --------------------------------------------------------------
' .Title: Excel VBA seemingly simple problem: Trim, Copy (insert), Concat on selected range
' .TitleLink: https://stackoverflow.com/questions/52548294/excel-vba-seemingly-simple-problem-trim-copy-insert-concat-on-selected-rang
' .Author: NewbieStackOr
' .AuthorLink: https://stackoverflow.com/users/10427336/newbiestackor
'End With ----------------------------------------------------------------------
'End With ======================================================================

loop through rows and columns to meet criteria

I would be very greatful if someone could help me with this issue...
I would like to have a excel macro which would go through first row and first column of the sheet2 to return the value if booth conditions are met in cell b3 in sheet1.
Conditions would be specified on sheet1; cell b1 would contain condition by which rows in sheet2 should be searched and cell b2 would contain condition by which columns in sheet2 should be searched. Result should be copied in cell b3 in sheet1.
Thanks in advance
Addition..............
I have this sub which goes through rows and looks for condition 1 (strDate) but I only managed to do this is column is fixed. I should add one more counter which would go through columns to meet condition 2 (strProduct) but I don
Sub LookUpValuesRCC2()
'
Dim shtData As Worksheet ' Sheet containing data
Dim shtOutput As Worksheet ' Output Sheet
Dim strDate As String ' Date - condition 1
Dim strProduct As String ' Product - condition 2
Dim i As Integer ' Counter in shtData Sheet
Dim j As Integer ' Counter in shtOutput Sheet
'
Set shtData = Worksheets("sheet2")
Set shtOutput = Worksheets("sheet1")
'
' Loop through "Data" Sheet Rows
For i = 1 To 1000
strDate = shtData.Cells(i, 1)
'
' Loop through dates in "Output" Sheet
' if date match then vrite values
For j = 1 To shtOutput.Cells(Rows.Count, 14).End(xlUp).Row
If shtOutput.Cells(j, 14) = strDate Then
shtOutput.Cells(j, 2) = shtData.Cells(i, 18)
End If
Next j
Next i
End Sub
First welcome to SO. Second, it's not 100% clear what your after because your code doesn't exactly match the description of what you want, or doesn't appear to me to do that.
I've written the below code based on what your description says, since the code you have doesn't get you want you want, so I am going to assume it needs modification anyway.
Comment if this doesn't satisfy your requirement.
Sub LookUpValuesRCC2()
Dim shtData As Worksheet ' Sheet containing data
Dim shtOutput As Worksheet ' Output Sheet
Dim strDate As Date ' Date - condition 1
Dim strProduct As String ' Product - condition 2
Dim strResult As String 'result to print
Dim rngFound As range, rngFoundAgain As range
Set shtData = Worksheets("sheet2")
Set shtOutput = Worksheets("sheet1")
strDate = shtOutput.range("B1").Value
strProduct = shtOutput.range("B2").Value
strResult = "Nothing Found"
With shData
'first look down the first column for the date
Set rngFound = .Columns(1).Find(strDate, lookat:=xlWhole)
If Not rngFound Is Nothing Then
'if that is found, look for the product in the row with the date
Set rngFoundAgain = rngFound.EntireRow.Find(strProduct, lookat:=xlWhole)
If Not rngFoundAgain Is Nothing Then strResult = rngFoundAgain.Value
End If
End With
shtData.range("B3") = strResult
End Sub

Resources