Search words in two columns and copy to another sheet - excel

In my problem:
First, I need to find "Unit Name" in Column B.
If it found "Unit Name" it should look for "First Name:" in Column D and copy 5 cell right. ("Obama" in I10)
Paste the name "Obama" to Unit Name sheet. (Paste "Obama" to Sheet "1" A1)
I am new in coding therefore i don't know too much about it. I tried with some codes but it is not efficient.
Here is an image to show my problem.
Sub Test()
Dim i As Integer
Dim m As Integer
Dim n As Integer
Dim z As Integer
For i = 1000 To 1 Step -1
If Range("B" & i).Value = "Unit Name" Then
m = 2
m = i + 1
n = i - 18
If Range("D" & n).Value = "First Name:" Then
m = Range("B" & m).Value + 1
Range("H" & n).Copy
Sheets(m).Range("B7").PasteSpecial xlPasteValues
End If
End If
Next i
End Sub

You don't need all those integer variables, you can use a few Range variables instead:
Sub find_name()
Dim mainWS As Worksheet, altWS As Worksheet
Dim unitCel As Range, fNameCell As Range
Set mainWS = Worksheets("Sheet2") 'CHANGE AS NEEDED
Set altWS = Worksheets("Sheet1")
With mainWS
Set unitCel = .Range("B:B").Find(What:="Unit Name")
If Not unitCel Is Nothing Then
Set fNameCell = .Range("D:D").Find(What:="First Name:").Offset(0, 5)
altWS.Range("A1").Value = fNameCell.Value
End If
End With
End Sub
May need to tweak this, depending on where your data is. I am assuming "Obama" could be any text, that is three columns right of column D, where "First Name:" is found.

Sub Shift_Over5()
Dim i As Long
'Sheet name should be a string
Dim SheetName As String
Dim FirstName As Range
Dim UnitName As Range
'Dim l As Byte --> I changed it to lUnitSheetLastrow, because we need to copy the data from sheet1 to sheet 1,2...
' then you need to check the last row of unit sheet and write data to the last row + 1.
Dim lUnitSheetLastrow As Long
Dim FirstMatch As Variant
Dim Start
Start = VBA.Timer
For i = 1 To 40000 Step 1
'For clear code and easy to follow, you need to mention the sheet you want to interact
'Here i use 'Activesheet', i assume that the current sheet is sheet1
If ActiveSheet.Range("A" & i).Value = "Unit Name" Then
' i think we dont need this code line, because we identified the cell in column B has value is "Unit Name"
'Set UnitName = Range("A:A").Find(what:="Unit Name")
' Here you dont need to use Offset
'SheetName = UnitName.Offset(1, 0).Value
SheetName = ActiveSheet.Range("A" & (i + 1)).Value
' Find "First Name" in 20 rows in column E.
' What happen if i<20, the nextline will show the error, because the minimum row is 1
If i < 40 Then
Set FirstName = ActiveSheet.Range("D1" & ":D" & i).Find(what:="First Name:")
Else
Set FirstName = ActiveSheet.Range("D" & i & ":D" & (i + 40)).Find(what:="First Name")
End If
' make sure the SheetName is not empty and Unit sheet is existing in you workbook then copy the first name to unit sheet
If SheetName <> "" And CheckWorkSheetAvailable(SheetName) Then
' Check the first name is not nothing
If Not FirstName Is Nothing Then
'Check if the cell B7 in unit sheet empty or not
If Worksheets(SheetName).Range("H7").Value = "" Then
'if empty, write to B7
Worksheets(SheetName).Range("H7").Value = FirstName.Offset(1, 0).Value
Else
'else, Find the lastrow in column D of unit sheet
lUnitSheetLastrow = Worksheets(SheetName).Cells(Worksheets(SheetName).Rows.Count, 1).End(xlUp).Row
'Write data to lastrow +1
Worksheets(SheetName).Range("A" & (lUnitSheetLastrow + 1)).Value = FirstName.Offset(, 1).Value
End If
End If
End If
'You forgot to put end if here
End If
Next i
Debug.Print Round(Timer - Start, 3)
End Sub
Function CheckWorkSheetAvailable(SheetName As String) As Boolean
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name = SheetName Then
CheckWorkSheetAvailable = True
Exit For
End If
Next
End Function
thank you everyone I found the answer.

Related

Obtain a list of information Pertaining to a Specific Month

I have trouble running this script to obtain Summary information for a specific month. I am explaining below the details of my workbook.
Tab 1 called "Schedule"
Tab 2 called "Results"
Tab 3 called "Sheet3"
I would like to obtain info from column C (Summary) in tab1 for the month of July. I am entering the month in tab2 and would like to run the macro and obtain all the results pertaining to the month of July.
Sub schedule()
Dim sch As Workbook
Dim schTot As Worksheet
Dim schRes As Worksheet
Dim i As Long
Dim j As Long
Let sch = Thisworkbook
Let schRes = sch.Worksheets("Results")
Let schTot = sch.Worksheets("Schedule")
For i = 1 To schTot.Range("A1").End(xlDown)
For j = 3 To schRes.Range("B3").End(xlDown)
If schTot.Cells(i, 1).Value = schRes.Cells(1, 2).Value Then
If schRes.Cells(j, 1).Value = "" Then
schTot.Rows(i).Copy
schRes.Cells(j, 1).Paste
Application.CutCopyMode = False
'Exit For
End If
End If
Next j
Next i
End Sub
Try this:
Option Explicit
Sub schedule()
Dim sch As Workbook
Dim schTot As Worksheet
Dim schRes As Worksheet
Dim i As Long
Dim j As Long
Dim strMonth As String
With ThisWorkbook
Set schRes = .Worksheets("Results")
Set schTot = .Worksheets("Schedule")
End With
schRes.Range("A3:C" & schRes.Cells(3, 1).End(xlDown).Row).ClearContents
strMonth = schRes.Cells(1, 2).Value
i = 2
j = 3
With schTot
Do Until .Cells(i, 1).Value = ""
If .Cells(i, 1).Value = strMonth Then
schRes.Range("A" & j & ":C" & j).Value = .Range("A" & i & ":C" & i).Value
j = j + 1
End If
i = i + 1
Loop
End With
End Sub
For your code, you just need to change following things to get it run:
-use "Set" instead of "Let"
Set sch = Thisworkbook
Set schRes = sch.Worksheets("Results")
Set schTot = sch.Worksheets("Schedule")
-return row's number in for loop condition
For i = 1 To schTot.Range("A1").End(xlDown).Row
For j = 3 To schRes.Range("B3").End(xlDown).Row
Then your code will be ok to run, but if your B3 cell in Results worksheet don't have value or following cells(i.e. B4,B5,B6...) doesn't have vale, your code will run infinitely and crush eventually.
Also, you copy a entire row in loop every single time which contain unnecessary cells. This will horribly slow down your code.
To speed up the code, I recommend to use auto filter to solve the problem:
Sub sechedule()
Dim sch As Workbook: Set sch = ThisWorkbook
Dim schTot As Worksheet: Set scTot = sch.Worksheets("Schedule")
Dim schRes As Worksheet: Set schRes = sch.Worksheets("Results")
Dim month As String
month = Range("B1").Value 'The month you inputted in Results worksheet
'I suppose you want to paste the result to Results worksheet starting from Cell A3, so the contents will be cleared first each time if somethings are in the result area:
If Range("A3").Value = "" Then Range("A3:C" & Range("A" & Rows.Count).End(xlUp).Row).ClearContents
With schTot
.Activate
.Range("A:C").AutoFilter Field:=1, Criterial:=month 'Choose data for specific month with auto filter
.Range("A2:C" & Range("A" & Rows.Count).End(xlUp).Row).SpecialCells(xlCellTypeVisible).Copy Destination:=schRes.Range("A3") '<--You can change the paste destination here
.ShowAllData
.Range("A:C").AutoFilter 'Cancel auto filter
End With
schRes.Activate
End Sub

Exce VBA how to generate a row count in that starts with specific row and stops at last row? Formula is flawed

So I have what might be a simple issue. I have a worksheet where I'm just hoping to generate a row count starting with cell A4. So A4 = 1, A5 = 2 , etc. The problem is I'm not sure how to configure this with the following goal:
1 - I'm hoping the count starts with cell A4 and ends the count at the final row with data.
The code I have below only works if I manually put A4 = 1, and also populates formulas past the last row unfortunately.
Please help if this is possible.
Sub V14()
With ThisWorkbook.Worksheets("DCT")
.Cells(5, 1).Resize(.Cells(.Rows.Count, 2).End(xlUp).Row - 1).Formula = "=IF(DCT!B5="""","""",DCT!A4+1)"
End With
End Sub
Write Formula to Column Range
The Code
Sub V14()
Const wsName As String = "DCT" ' Worksheet Name
Const tgtRow As Long = 4 ' Target First Row Number
Const tgtCol As String = "A" ' Target Column String
Const critCol As String = "B" ' Criteria Column String
' Define worksheet ('ws').
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(wsName)
' Define Last Non-Empty Cell ('cel') in Criteria Column ('critCol').
Dim cel As Range
Set cel = ws.Cells(ws.Rows.Count, critCol).End(xlUp)
' Define Target Column Range ('rng').
Dim rng As Range
Set rng = ws.Cells(tgtRow, tgtCol).Resize(cel.Row - tgtRow + 1)
' Define Target Formula ('tgtFormula').
Dim tgtFormula As String
tgtFormula = "=IF('" & wsName & "'!" & critCol & tgtRow _
& "="""","""",MAX('" & wsName & "'!" & tgtCol _
& "$" & tgtRow - 1 & ":" & tgtCol & tgtRow - 1 & ")+1)"
' Write Target Formula to Target Range.
rng.Formula = tgtFormula
' If you just want to keep the values:
'rng.Value = rng.Value
End Sub
I think you might just need an extra IF:
Sub V14()
With ThisWorkbook.Worksheets("DCT")
.Cells(4, 1).Resize(.Cells(.Rows.Count, 2).End(xlUp).Row - 1).Formula = "=IF(DCT!B4="""","""",IF(A3="""",1,SUM(DCT!A3,1)))"
End With
End Sub
Report any question you have or bug you have encountered. If, according to your judgment, this answer (or any other) is the best solution to your problem you have the privilege to accept it (link).
Dim target As String
Dim lastrow As Long
target = "A4"
lastrow = ActiveSheet.UsedRange.Rows.count
'for example
Range(target) = "1"
Range(target).Offset(1, 0) = "2"
Range(Range(target),Range(target).Offset(1, 0)).Select
Selection.AutoFill Destination:=Range(target & ":A" & lastrow + Range(target).Row - 1), Type:=xlFillDefault
You only got to change the target cell, this does the rest.

Copying values from one sheet based on condition to another workbook

I've written some code that assigns each item in a list a code based on row #. What I want to do from there is choose a copy all information from each row that corresponds with a chosen code, then paste it to another workbook. I've been having some trouble. Here's the code:
Sub LSHP_Distribute()
Dim wbLSHP As Workbook
Dim wsLSHP As Worksheet
Dim CodeRange As Range
Dim FirstRow As Long
Dim LastRow As Long
Dim wbTEST As Workbook
Set wbLSHP = ActiveWorkbook
Set wsLSHP = wbLSHP.Sheets("Sheet1")
'Generate codes for newly added items
Application.ScreenUpdating = False
'Turn off screen updating
With wsLSHP
FirstRow = .Range("F3").End(xlDown).Row + 1
LastRow = .Range("B6", .Range("B6").End(xlDown)).Rows.Count + 5
Set CodeRange = .Range("$F$" & FirstRow, "$F$" & LastRow)
End With
For Each cell In CodeRange
If cell = "" Then
If cell.Row Mod 3 = 0 Then
cell.Value = "1"
ElseIf cell.Row Mod 3 = 1 Then
cell.Value = "2"
ElseIf cell.Row Mod 3 = 2 Then
cell.Value = "3"
Else
End If
End If
Next cell
'Open Spreadsheets to Distribute Items
Dim PasteRow As Long
Dim i As Integer
Set wbTEST = Workbooks.Open(Filename:="V:\Test.xlsx")
PasteRow = wbTEST.Sheets("Sheet1").Range("B6").End(xlDown).Row + 1
Below is where I'm having the problem
wbLSHP.Activate
For Each cell In CodeRange
If cell = "1" Then
Range(ActiveCell.Offset(0, -5), ActiveCell.Offset(0, 20)).Select
Selection.Copy
wbTEST.Sheets("Sheet1").Cells(PasteRow, 1).PasteSpecial xlPasteValues
PasteRow = PasteRow + 1
Else
End If
Next cell
End Sub
First problem is the For loop isn't copying the correct range in "CodeRange", the second problem is it only copies once before I get an Automation Error. Let me know if you have any questions, or know of a more efficient way to write this code.
Thanks so much for your time!
Your range is defined to Start in F3 and end in BSomething, but you store to CodeRange only the F column.
Set CodeRange = .Range("$F$" & FirstRow, "$F$" & LastRow)
Try using:
Set CodeRange = .Range("$B$" & FirstRow, "$F$" & LastRow)
I suggest instead of Copy and Paste, assign the value to a variable and put the value of the variable on wbTEST.

Convert Text to Rows instead of Text to Columns

I have a text string that is using the ^ symbol as a delimiter.
I need to separate the text into new rows rather than new columns.
I need to create new rows to not overwrite the next line of data below it.
Is this possible without using a macro? I'm not against using one, I just wouldn't know where to start to write it.
Below is a pic of some sample data. The top part is how it's listed, and the bottom (in yellow) is how I would like it.
Using Excel 2010 on Windows 7 Pro.
Thanks to those that responded. A friend was able to help by providing the following code:
Sub Breakout()
Application.ScreenUpdating = False
LR = Cells(Rows.Count, 1).End(xlUp).Row
For r = LR To 2 Step -1
Set MyCell = Cells(r, 1)
Arry = Split(MyCell.Value, "^")
For c = 0 To UBound(Arry)
If c > 0 Then MyCell.Offset(c, 0).EntireRow.Insert
MyCell.Offset(c, 0) = Arry(c)
Next c
Next r
End Sub
Could try something like this:
Sub reArrange()
Dim inFirstRng As Range
Dim inRng As Range
Dim inCur As Variant
Dim outFirstRng As Range
Dim outCurRng As Range
Dim ws As Worksheet
'CHANGE ARGUMENT TO YOUR SHEET NAME
Set ws = Worksheets("Sheet2")
With ws
'CHANGE ARGUMENT TO WHATEVER THE FIRST CELL OR YOUR DATA INPUT IS IN COLUMN A
Set inFirstRng = .Range("A3")
Set inRng = .Range(inFirstRng, inFirstRng.End(xlDown))
'CHANGE ARGUMENT TO WHATEVER THE FIRST CELL OR YOUR DATA OUTPUT IS IN COLUMN A
Set outFirstRng = .Range("A9")
Set outCurRng = outFirstRng
End With
For Each cell In inRng.Cells
inCur = WorksheetFunction.Transpose(Split(cell.Value, "^"))
outCurRng.Resize(UBound(inCur), 1).Value = inCur
With ws
.Range("G" & outCurRng.Row & ":L" & outCurRng.Row).Value = _
.Range("G" & cell.Row & ":L" & cell.Row).Value
End With
Set outCurRng = outCurRng.Offset(UBound(inCur), 0)
Next cell
ws.Range("F" & outFirstRng.Row & ":F" & outCurRng.Row - 1).Value = 1
End Sub

Excel 2007 VBA runtime error when selecting worksheet with variable

I've been recently getting back into VBA and have been testing out a concept of Adding Worksheets by the string in a variable. I've been able to get the worksheets to add successfully and the last two lines of my code are simply to select the sheet name of the variable and then select cell A + the row number that is stored in another variable
In Sheet1, Column A, starting in A1, I have a list of 8 different names that cycles through:
Bob
Jeff
Max
Steve
Rosie
Pippa
Penelope
Rob
I am expecting the macro to end on Sheet "Rob" with cell A9 selected, however i get a runtime 1004 error
I have stepped through the code and it is selecting the sheet correctly with the variable, but when it tries to select row A9, the error presents
My code is below:
Sub Add_worksheets()
Dim sheetName As String
Dim rownum As Integer
rownum = 1
Range("A" & rownum).Select
sheetName = ActiveCell.Value
Do Until Range("A" & rownum).Value = ""
Range("A" & rownum).Select
sheetName = CStr(ActiveCell.Value)
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = sheetName
Sheets("sheet1").Select
rownum = rownum + 1
Loop
Sheets(sheetName).Select
Range("A" & rownum).Select
End Sub
Any help would be greatly appreciated
I also suggest you add if-else to check if the sheet name exists.. Why do you want to select? I do not support selections, since you need it you may try this: Because when you are incrementing rownum it goes to 10th cell, that means, Sheetname no longer has a name but empty..
Dim sheetName As String
Dim rownum As Integer
Dim WS as WorkSheet
rownum = 1
sheetName = Range("A" & rownum).Value '-- remove select
Do Until Range("A" & rownum).Value = ""
Range("A" & rownum).Select
sheetName = CStr(ActiveCell.Value)
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = sheetName
Set WS = Sheets(sheetName)
Sheets("sheet1").Select
rownum = rownum + 1
Loop
rownum = rownum - 1 '-- here
WS.Activate
Range("A" & rownum).Value = rownum
Or you may just use an array to do the creation of the sheets and then select a sheet later....Instead of going back and forth to first sheet...with names..
Sub addSheets()
Dim rowNum as Integer
Dim Ws as WorkSheet
Dim vArray as Variant
'-- creates one dimensional array
vArray = WorkSheetFunction.Transpoe(Sheets(1).Range("A1:A9"))
For rownum = Lbound(vArray) to Ubound(vArray)
If IsEmpty(vArray(rowNum)) Then
On Error Resume Next
Set Ws = Sheets(vArray(rowNum))
If Err.Number <> 0 Then '--no such sheet, so add it
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = vArray(rowNum)
Set Ws = Sheets(vArray(rowNum))
End If
End IF
Next rownum
Ws.Activate
Ws.Range("A1").offset(rownum).value = rownum
End Sub

Resources