im using this code and it works but somehow stops after the first row is copied. Do you have an idea why? Otherwise it seems to do what it should do, thanks! The searched term is nosh and in sheet 1 (Tabelle1) it is always found in this format D:XXX(NOSH) with XXX changing for different company names.
Public Sub Kopieren()
Dim WkSh_Q As Worksheet
Dim WkSh_Z As Worksheet
Dim rZelle As Range
Dim aUeberschr As Variant
Dim iIndx As Integer
Dim iSpalte As Integer
aUeberschr = Array("NOSH")
Application.ScreenUpdating = False
Set WkSh_Q = Worksheets("Tabelle1") ' das Quell-Tabellenblatt
Set WkSh_Z = Worksheets("Tabelle2") ' das Ziel-Tabellenblatt
With WkSh_Q.Rows
For iIndx = 0 To UBound(aUeberschr)
Set rZelle = .Find(aUeberschr(iIndx), LookAt:=xlWhole, LookIn:=xlValues)
If Not rZelle Is Nothing Then
iSpalte = iSpalte + 1
WkSh_Q.Columns(rZelle.Column).Copy Destination:=WkSh_Z.Columns(iSpalte)
End If
Next iIndx
End With
Application.ScreenUpdating = True
End Sub
Edit:
And I would need to copy every coloumn with NOSH to be copied to "Tabelle2"
I found this Code to search the whole first sheet and repeat the task but it seems to copy just the names of the stocks (BAYER etc) to every row.
Private Sub CommandButton1_Click()
Dim WkSh_Q As Worksheet, WkSh_Z As Worksheet
Dim rZelle As Range, aUeberschr As Variant
Dim strErste As String
Dim iIndx As Long, iSpalte As Long
aUeberschr = Array(NOSH)
Application.ScreenUpdating = False
Set WkSh_Q = Worksheets("Tabelle1") ' das Quell-Tabellenblatt
Set WkSh_Z = Worksheets("Tabelle2") ' das Ziel-Tabellenblatt
With WkSh_Q.Cells
For iIndx = 0 To UBound(aUeberschr)
Set rZelle = .Find(aUeberschr(iIndx), LookAt:=xlWhole, LookIn:=xlValues)
If Not rZelle Is Nothing Then
strErste = rZelle.Address
Do
iZeile = iZeile + 1
WkSh_Q.Rows(rZelle.Row).Copy Destination:=WkSh_Z.Rows(iZeile)
Set rZelle = .FindNext(rZelle)
Loop Until strErste = rZelle.Address
End If
Next iIndx
End With
Application.ScreenUpdating = True
End Sub
Using the second code you posted. I "cleaned" up the code a bit and also modified the code to do your desired task. When you are doing a partial search ("NOSH") make sure to use LookAt:=xlPart instead of LookAt:=xlWhole. Also in your case, if you want to copy the columns use WkSh_Q.Columns(rZelle.Column).Copy Destination:=WkSh_Z.Columns(iZeile) instead of WkSh_Q.Rows(rZelle.Row).Copy Destination:=WkSh_Z.Rows(iZeile)
Dim WkSh_Q As Worksheet, WkSh_Z As Worksheet
Dim rZelle As Range, aUeberschr As String
Dim strErste As String
Dim iZeile As Integer
aUeberschr = "NOSH"
Set WkSh_Q = Worksheets("Tabelle1") ' das Quell-Tabellenblatt
Set WkSh_Z = Worksheets("Tabelle2") ' das Ziel-Tabellenblatt
With WkSh_Q.Cells
Set rZelle = .Find(aUeberschr, LookAt:=xlPart, LookIn:=xlValues)
If Not rZelle Is Nothing Then
strErste = rZelle.Address
Do
iZeile = iZeile + 1
WkSh_Q.Columns(rZelle.Column).Copy Destination:=WkSh_Z.Columns(iZeile)
Set rZelle = .FindNext(rZelle)
Loop Until strErste = rZelle.Address
End If
End With
Hope that helps, good luck.
Related
I have a seemingly simple goal to turn the content of column B into comments of column A.
I have tried using the following code from #Dy.Lee mentioned here, but unfortunately it gives me a Run-time error '1004' Application-defined or object-defined error...
Sub Komentari()
Dim rngDB As Range, rngComent As Range
Dim rng As Range
Dim cm As Comment, i As Integer
Set rngComent = Range("A1:A50")
Set rngDB = Range("B1:B50")
For Each rng In rngComent
i = i + 1
If Not rng.Comment Is Nothing Then
rng.Comment.Delete
End If
Set cm = rng.AddComment
With cm
.Visible = False
.Text Text:=rngDB(i).value
End With
Next rng
End Sub
Can somebody, please, spot the mistake or suggest a better solution for this?
I'd go this way (explanations in comments):
Public Sub Komentari()
Dim rng As Range
With Range("A1:A50") ' reference comments range
.ClearComments ' clear its comments
For Each rng In .Offset(, 1).SpecialCells(xlCellTypeConstants) ' loop through refrenced range adjacent not empty cells
With rng.Offset(, -1).AddComment ' add comment to current rng corresponding comment range cell
.Visible = False
.Text rng.Value2
End With
Next
End With
End Sub
Sub Komentari()
Dim rngDB As Range, rngComent As Range
Dim rng As Range
Dim cm As Comment, i As Integer
Set rngComent = Range("A1:A50")
For Each rng In rngComent
i = i + 1
If Not rng.Range("B1").Comment Is Nothing Then
rng.Range("B1").Comment.Delete
End If
rng.Range("B1").AddComment (rng.Text)
Next rng
End Sub
Something like the following where you can use Offset to get the adjacent range, you drop the = when adding the text value to the comment, test that there is actually a value present first as well, and ensure you state the sheet to avoid implicit Activesheet reference.
Option Explicit
Public Sub Komentari()
Dim rngComent As Range
Dim rng As Range, cm As Comment
With ThisWorkbook.Worksheets("Sheet1")
Set rngComent = .Range("A1:A50")
For Each rng In rngComent
If Not rng.Comment Is Nothing Then
rng.Comment.Delete
End If
Set cm = rng.AddComment
With cm
.Visible = False
If rng.Offset(, 1) <> vbNullString Then .Text rng.Offset(0, 1).Value
End With
Next
End With
End Sub
Rather than add blank comments you could also flip this round to:
Option Explicit
Public Sub Komentari()
Dim rngComent As Range
Dim rng As Range, cm As Comment
With ThisWorkbook.Worksheets("Sheet1")
Set rngComent = .Range("A1:A50")
For Each rng In rngComent
If Not rng.Comment Is Nothing Then
rng.Comment.Delete
End If
If rng.Offset(, 1) <> vbNullString Then
Set cm = rng.AddComment
With cm
.Visible = False
.Text rng.Offset(0, 1).Value
End With
End If
Next
End With
End Sub
I am creating a macro that is supposed to separate and add new worksheets based off one worksheet with all the data in it.
It won't run and I'm not sure why.
My code keeps hitting a Run Time Error '9': Script out of range. I'm not sure if it has something to do with the first sub or the second sub.
The error occurs on line 16:
Set wsMain = wbMain.Sheets("MAIN")
First sub:
Option Explicit
Sub main()
Dim wbMain As Workbook
Dim wsMain As Worksheet
Dim rngMain As Range
Dim RngCategoryOne As Range
Dim RngCategoryTwo As Range
Dim RngCategoryThree As Range
Dim RngCategoryFour As Range
Dim RngCategoryFive As Range
Dim RngCategorySix As Range
Dim rng As Range
Dim SheetNames As Variant
Dim str As Variant
Set wbMain = ActiveWorkbook
Set wsMain = wbMain.Sheets("MAIN")
Set rngMain = wsMain.Range("F2:F3000")
For Each rng In rngMain
Select Case rng
Case "HO NMX_AMO", "HO NMX_EUR", "WTI NMX", "DIESEL OHR EIA_AMO"
If RngCategoryOne Is Nothing Then
Set RngCategoryOne = rng
Else
Set RngCategoryOne = Union(rng, RngCategoryOne)
End If
Case "WTI NMX_AMO"
If RngCategoryTwo Is Nothing Then
Set RngCategoryTwo = rng
Else
Set RngCategoryTwo = Union(rng, RngCategoryTwo)
End If
Case "NG HH NMX"
If RngCategoryThree Is Nothing Then
Set RngCategoryThree = rng
Else
Set RngCategoryThree = Union(rng, RngCategoryThree)
End If
Case "RBOB NMX_EUR", "RBOB NMX_AMO"
If RngCategoryFour Is Nothing Then
Set RngCategoryFour = rng
Else
Set RngCategoryFour = Union(rng, RngCategoryFour)
End If
Case "GO ICE_AMO"
If RngCategoryFive Is Nothing Then
Set RngCategoryFive = rng
Else
Set RngCategoryFive = Union(rng, RngCategoryFive)
End If
Case "C3 CONW INW OPIS_APO, C3 MBEL TET OPIS_APO"
If RngCategorySix Is Nothing Then
Set RngCategorySix = rng
Else
Set RngCategorySix = Union(rng, RngCategorySix)
SheetNames = Array("AT, LB, LC, AS", "AO", "LN", "RF, RA", "ULA2", "8K, BO")
For Each str In SheetNames
Call AddNewWorksheet(wbMain, str)
Next str
wbMain.Sheets("AT, LB, LC, AS").Range("A1:A" & RngCategoryOne.Count) = RngCategoryOne.Value
wbMain.Sheets("AO").Range("A1:A" & RngCategoryTwo.Count) = RngCategoryTwo.Value
wbMain.Sheets("LN").Range("A1:A" & RngCategoryThree.Count) = RngCategoryThree.Value
wbMain.Sheets("RF, RA").Range("A1:A" & RngCategoryFour.Count) = RngCategoryFour.Value
wbMain.Sheets("ULA2").Range("A1:A" & RngCategoryFive.Count) = RngCategoryFive.Value
wbMain.Sheets("8K, BO").Range("A1:A" & RngCategorySix.Count) = RngCategorySix.Value
wsMain.Activate
wsMain.Range("A1").Select
End If
End Select
Next
End Sub
Second Sub:
Sub AddNewWorksheet(ByRef wb As Workbook, ByVal wsName As Variant)
With wb.Sheets
.Add(after:=wb.Sheets(.Count)).Name = wsName
End With
End Sub
I would like to atomatize an excel process using VBA.
The script has to go cell by cell in a selected area on Sheet3. Each cell contains a number or is blank.
The script will go and search for the value of each cell in a specific range on Sheet2. When it finds something the content of the whole row where it was found must go bold.
If it finds nothing it will just procede to the next cell.
After browsing here on stackoverflow and different guides I've managed to put together a script. It has no errors but it doesn't do Anything.
Sub MacroText()
Dim xlRng As Range
Dim rng As Range
Dim xlSht As Worksheet
Dim sht As Worksheet
Dim iLastRow As Integer
Dim iRow As Integer
Dim bFound As Boolean
Dim xCell As Range
Dim xlCell As Range
Dim valueToFind As String
bFound = False
Set sht = ActiveWorkbook.Worksheets("Sheet3")
Set xlSht = ActiveWorkbook.Worksheets("Sheet2")
Set rng = Selection
Set xlRng = ActiveWorkbook.Worksheets("Sheet2").Range("A:A")
iLastRow = xlSht.Range("A1").End(xlDown).Row
Set xlRng = xlSht.Range("A1:A" & iLastRow)
For Each xCell In rng
valueToFind = xCell.Value
For Each xlCell In xlRng
Worksheets("Sheet2").Activate
If xlCell.Value = valueToFind Then
bFound = True
iRow = xlCell.Row
Rows(iRow).Font.Bold = True
End If
If bFound = True Then Exit For
End
Next xlCell
Next xCell
End Sub
I am assuming that it has to be something with positioning within the code but I couldn't find any information for that.
After working on this for 12 hours I would really appreciate your help.
Cheers!
You could use the Find method to achieve this instead of the second loop
Sub MacroText()
Dim xlRng As Range
Dim rng As Range
Dim xlSht As Worksheet
Dim sht As Worksheet
Dim iLastRow As Long
Dim iRow As Long
Dim bFound As Boolean
Dim xCell As Range
Dim xlCell As Range
Dim valueToFind As String
Dim FoundRange As Range
bFound = False
Set sht = ActiveWorkbook.Worksheets("Sheet3")
Set xlSht = ActiveWorkbook.Worksheets("Sheet2")
Set rng = Selection
Set xlRng = ActiveWorkbook.Worksheets("Sheet2").Range("A:A")
iLastRow = xlSht.Range("A1").End(xlDown).Row
Set xlRng = xlSht.Range("A1:A" & iLastRow)
For Each xCell In rng
Set FoundRange = Nothing
Set FoundRange = xlRng.Find(what:=xCell.Value2)
If Not FoundRange Is Nothing Then
FoundRange.EntireRow.Font.Bold = True
End If
Next xCell
End Sub
For Each xlCell In xlRng
Worksheets("Sheet2").Activate
If xlCell.Value = valueToFind Then
xlCell.EntireRow.Font.Bold = True
End If
Next xlCell
I don't know what thing you are not getting, but I assumed that you are not getting desired row as bold. Replace the above code with your's for loop and run.
I didn't tested it, but am uncertain about not working.
I'm looking to insert a new blank row after every instance of HDR in the sheet. I cannot figure out how to make the code move beyond the first instance to continue through the rest of the sheet.
Sub NewRowInsert()
Dim SearchText As String
Dim GCell As Range
SearchText = "HDR"
Set GCell = Cells.Find(SearchText).Offset(1)
GCell.EntireRow.Insert
End Sub
Try this code
Sub Test()
Dim a() As Variant
Dim found As Range
Dim fStr As String
Dim fAdd As String
Dim i As Long
fStr = "HDR"
Set found = Cells.Find(What:=fStr, After:=Range("A1"), LookIn:=xlValues, LookAt:=xlWhole)
If Not found Is Nothing Then
fAdd = found.Address
Do
ReDim Preserve a(i)
a(i) = found.Offset(1).Address
i = i + 1
Set found = Cells.FindNext(found)
Loop Until found.Address = fAdd
End If
If i = 0 Then Exit Sub
For i = UBound(a) To LBound(a) Step -1
Range(a(i)).EntireRow.Insert
Next i
End Sub
Another option
Sub Test()
Dim a() As Variant
Dim oRange As Range
Dim found As Range
Dim fStr As String
Dim fAdd As String
fStr = "HDR"
Set found = Cells.Find(What:=fStr, After:=Range("A1"), LookIn:=xlValues, LookAt:=xlWhole)
If Not found Is Nothing Then
fAdd = found.Address
Do
If oRange Is Nothing Then Set oRange = found.Offset(1) Else Set oRange = Union(oRange, found.Offset(1))
Set found = Cells.FindNext(found)
Loop Until found.Address = fAdd
End If
If Not oRange Is Nothing Then oRange.EntireRow.Insert
End Sub
Sub NewRowInsert()
Dim SearchText As String
Dim GCell As Range
Dim NumSearches As Integer
Dim i As Integer
SearchText = "HDR"
NumSearches = WorksheetFunction.CountIf(Cells, SearchText)
Set GCell = Cells(1, 1)
For i = 1 To NumSearches
Set GCell = Cells.Find(SearchText, After:=GCell, SearchOrder:=xlByRows, SearchDirection:=xlNext).Offset(1)
GCell.EntireRow.Insert
Next i
End Sub
I'm trying to figure out a problem in Excel. I am getting an Out of Memory error and I suspect that's not the problem but I don't really know.
Basically, I'm trying to make a macro that searches for a column within 5 tabs in a spreadsheet (the column can be in any of the 5 and it changes a lot) and when it finds it, does a vlookup match to return the column to the appropriate place in the master tab. Here is my code below which seems like it should work but I get the Out of Memory error. the line that is highlighted when I go to debug is the first Vrange = rB line in the if statement.
Dim i As Integer
Dim r As Range
'
Dim wsMaster As Worksheet: Set wsMaster = Workbooks("LBImportMacroTemplate.xlsm").Worksheets("MasterTab")
Dim wsB As Worksheet: Set wsB = Workbooks("LBImportMacroTemplate.xlsm").Worksheets("B")
Dim wsE As Worksheet: Set wsE = Workbooks("LBImportMacroTemplate.xlsm").Worksheets("E")
Dim wsL As Worksheet: Set wsL = Workbooks("LBImportMacroTemplate.xlsm").Worksheets("L")
Dim wsI As Worksheet: Set wsI = Workbooks("LBImportMacroTemplate.xlsm").Worksheets("I")
Dim wsT As Worksheet: Set wsT = Workbooks("LBImportMacroTemplate.xlsm").Worksheets("T")
'
Dim rBHeading As Range: Set rBHeading = wsB.Range("A2:ZA2")
Dim rEHeading As Range: Set rEHeading = wsE.Range("A2:ZA2")
Dim rLHeading As Range: Set rLHeading = wsL.Range("A2:ZA2")
Dim rIHeading As Range: Set rIHeading = wsI.Range("A2:ZA2")
Dim rTHeading As Range: Set rTHeading = wsT.Range("A2:ZA2")
'
Dim rB As Range: Set rB = wsB.Range("A:ZA")
Dim rE As Range: Set rE = wsE.Range("A:ZA")
Dim rL As Range: Set rL = wsL.Range("A:ZA")
Dim rI As Range: Set rI = wsI.Range("A:ZA")
Dim rT As Range: Set rT = wsT.Range("A:ZA")
'
Dim mf_iA_TEXT As String: mf_iA_TEXT = "iA"
'
If Application.CountIf(rBHeading, "iA") = 1 Then
Vrange = rB
Mrange = rBHeading
ElseIf Application.CountIf(rEHeading, "iA") = 1 Then
Vrange = rE
Mrange = rEHeading
ElseIf Application.CountIf(rLHeading, "iA") = 1 Then
Vrange = rL
Mrange = rLHeading
ElseIf Application.CountIf(rIHeading, "iA") = 1 Then
Vrange = rI
Mrange = rIHeading
Else
Vrange = rT
Mrange = rTHeading
End If
'
Dim mf_iA As Variant: mf_iA = Application.Match(mf_iA_TEXT, Mrange, 0)
'
With ActiveSheet
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
MsgBox lastrow
End With
'
For i = 2 To lastrow
wsMaster.Cells(i, 2) = Application.VLookup(wsMaster.Cells(i, 1), Vrange, mf_iA, 0)
Next i
'
End Sub
I also tried to accomplish this with a case statement but I felt like I got further with the above code. If you could please let me know if this code is dumb, or if I can solve the Out of Memory error, I would greatly appreciate it. If I can get this to work, I will be copying the process with many many more columns, in case that matters. Thanks!!
To get you started, the first 56 lines of code could be written as,
Dim v As Long, vWSs As Variant, Mrange As Range, Vrange As Range, mf_iA as long
Dim wsMaster As Worksheet: Set wsMaster = Workbooks("LBImportMacroTemplate.xlsm").Worksheets("MasterTab")
Dim mf_iA_TEXT As String: mf_iA_TEXT = "iA"
vWSs = Array("B", "E", "L", "I", "T")
With Workbooks("LBImportMacroTemplate.xlsm")
mf_iA = 0: Set Mrange = Nothing: Set Vrange = Nothing
For v = LBound(vWSs) To UBound(vWSs)
If CBool(Application.CountIf(.Sheets(vWSs(v)).Range("A2:ZA2"), mf_iA_TEXT)) Then
Set Mrange = .Sheets(vWSs(v)).Range("A2:ZA2")
Set Vrange = .Sheets(vWSs(v)).Range("A:ZA")
' added the column number assignment on the next line
mf_iA = application.match(mf_iA_TEXT, Mrange, 0)
Exit For
End If
Next v
End With
if mf_iA = 0 then msgbox "Stop here! " & mf_iA_TEXT & "not found!"
'assumed that Mrange and Vrange are not nothing at this point
' and that mf_iA is the numerical column index number for mf_iA_TEXT
'do something with them
Set Mrange = Nothing
Set Vrange = Nothing
Set wsMaster = Nothing
That takes you to the end of the If/ElseIf/End If where you can continue processing. The last three are just reminders to manually set the ranges and workbook object to nothing after you are done with them.