I'm writing a macro to concatenate a few columns into another column for a sheet that will eventually have thousands of rows. For the sake of testing I'm using four rows of data. My issue is that the Cells(i,25).Value is not populating when I run the following code. The code isn't breaking and I'm not getting any error messages. I tried assigning a 2 to column 26 using Cells(i,26) and that wasn't working either.
Sub concat()
Dim i As Long
Dim add As String
i = 1
Do Until IsEmpty(Cells(i, 1))
add = Cells(i, 14).Value
Cells(i, 25).Value = Cells(i, 1).Value & " " & Cells(i, 2).Value & " " & Left(add, 3)
i = i + 1
Loop
End Sub
Any help or recommendations would be greatly appreciated!
I recommend you change the code a little. I have used the IsEmpty command before and it's not the most suitable one for this.
Sub concat()
Dim i As Long
Dim add As String
Dim last_1 As Long
Dim last_2 As Long
Dim last_14 As Long
Dim lastCell As Long
last_1 = Sheets("test3").Cells(Rows.Count, 1).End(xlUp).Row
last_2 = Sheets("test3").Cells(Rows.Count, 2).End(xlUp).Row
last_14 = Sheets("test3").Cells(Rows.Count, 14).End(xlUp).Row
lastCell = WorksheetFunction.Max(last_1 , last_2, last_14)
For i = 1 To lastCell
add = Sheets("test3").Cells(i, 14).Value
Sheets("test3").Cells(i, 25).Value = Sheets("test3").Cells(i, 1).Value & " " & Sheets("test3").Cells(i, 2).Value & " " & Left(add, 3)
Next i
End Sub
Related
Hi I'm trying to create a VBA code that fills the entire column G values with Column E - Column F (so E2-F2 = G2) but I keep getting mismatch error. The values start from the second row and I have created a loop to run down the columns.
This is the code I have so far.
Sub RemainingHours()
Dim i As Integer
i = 2
With Sheets("Opt")
While Not IsEmpty(Cells(5, i).Value)
Cells(7, i).Value = Cells(6, i).Value - Cells(5, i).Value
i = i + 1
Wend
End With
End Sub
Thank you!
Rather than looping you could try using Evaluate.
Sub RemainingHours()
Dim rng As Range
Dim Res As Variant
With Sheets("Opt")
Set rng = .Range("E2", .Range("E" & Rows.Count).End(xlUp))
End With
Res = Evaluate(rng.Offset(, 1).Address & "-" & rng.Address)
rng.Offset(, 2).Value = Res
End Sub
I have a DATA sheet which contains data rows as follows:
And I have a sheet named ROWBUILDER that has formulas and produces results like this:
I would like to write a VBA code that will cycle through every row in the ROWBUILDER sheet and output data to a new worksheet.
NOTE: The ROWBUILDER sheet must remain as is. Only the resulting data must be copied to the OUTPUT sheet.
I have no idea how to do it and from where to start. Will appreciate any help, examples or links.
Many thanks in advance!
This moves all the data to one output sheet.
Sub MoveROWBUILDER()
Sheets("ROWBUILDER").Range("A1").CurrentRegion.Copy
Sheets("Output").Range("A1").PasteSpecial xlPasteValues
End Sub
If you are looking for one sheet per row, try this. You may run into a limit depending on memory and the amount of data.
Sub DataToSheets()
Dim sh As Worksheet
Dim rowCount As Integer, colCount As Integer
Dim i As Integer, j As Integer
Dim data() As Variant
Sheets("ROWBUILDER").Select
rowCount = Range("A1").CurrentRegion.Rows.Count
colCount = Range("A1").CurrentRegion.Columns.Count
data() = Sheets("ROWBUILDER").Range("A1").CurrentRegion.Value2
For i = 2 To rowCount
Set sh = Sheets.Add(After:=ActiveSheet)
sh.Name = "Data" & (i - 1)
For j = 1 To colCount
sh.Cells(1, j) = data(1, j)
sh.Cells(2, j) = data(i, j)
Next j
Next i
End Sub
If you can estimate the maximum number of rows in your data sheet then - instead of cycling through every row - you can use
rowbuilder.Range("A1:B" & lastrow).Copy
newworksheet.Range("A1").PasteSpecial xlValues
Let me try this again now that I have a better idea of what you need.
You can process all of the rows at once using dynamics arrays in ROWBUILDER. Set C1 in ROWBUILDER to
=COUNTA(DATA!A:A) - 1
Then set A2 to
=OFFSET(DATA!A2,0,0,C1,1) & " " & OFFSET(DATA!B2,0,0,C1,1)
This will spill all of the full names to column A. You can then set B2 to
=OFFSET(DATA!H2,0,0,C1,1) & " " & OFFSET(DATA!G2,0,0,C1,1) & " " & OFFSET(DATA!F2,0,0,C1,1) & OFFSET(DATA!E2,0,0,C1,1)
This will spill the Full Address to Column B. IF you still need to copy it to OUTPUT, then this code should do the job.
Range("A2#").Copy
offsetrows = Sheets("OUTPUT").Range("A1").CurrentRegion.Rows.Count
Sheets("OUTPUT").Select
Range("A1").Offset(offsetrows, 0).Select
Selection.PasteSpecial xlPasteValues
You can use loop like this:
numberRows = Range("A2").End(xlToDown).Row
Sheets.Add.Name = "OUTPUT"
For i = 2 To numberRows
Sheets("OUTPUT").Cells(i, 1).Value = Sheets("DATA").Cells(i, 1).Value
Sheets("OUTPUT").Cells(i, 2).Value = Sheets("DATA").Cells(i, 8).Value & " " & Sheets("DATA").Cells(i, 7).Value & " " & Sheets("DATA").Cells(i, 6).Value & " " & Sheets("DATA").Cells(i, 5).Value
Next i
I have 3 sheets: DATA, BUILD and RESULT.
DATA - contains all data
BUILD - 1 row that is iterated through VBA procedure (below) and a command button.
RESULT - where I need to put every iterated row of BUILD table.
The following part of the code is expected to add new row to a RESULTS table.
In a RESULTS sheet, rows are copied sometimes in row 2567, sometimes in 237 etc.
I can't understand the logic how VBA determines the row it puts copied rows.
Sheets("RESULTS").Range("A2" & i + 1).Value = Sheets("BUILD").Range("D4").Value 'League Name
Sheets("RESULTS").Range("B2" & i + 1).Value = Sheets("BUILD").Range("E4").Value 'Home Team
Sheets("RESULTS").Range("C2" & i + 1).Value = Sheets("BUILD").Range("F4").Value 'Away Team
This is the full code:
Sub btn_NextMatch()
Application.ScreenUpdating = False
Application.Volatile
Dim Last_row As Double
Dim Last_Col As Integer
Dim i As Integer
Dim sheet As String
sheet = ActiveSheet.Name
Sheets("BUILD").Select
i = Range("A1").Value
Sheets("DATA").Select
Last_row = Range("A" & Rows.Count).End(xlUp).Row
Last_Col = ActiveSheet.Cells.Find(What:="*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, LookIn:=xlValues).Column
Last_colletter = Split(Cells(1, Last_Col).Address, "$")(1)
If i = Last_row Then
i = 1
End If
Sheets("BUILD").Range("C2").Value = Sheets("DATA").Range("C" & i + 1).Value 'MatchID
Sheets("BUILD").Range("D4").Value = Sheets("DATA").Range("D" & i + 1).Value 'League Name
Sheets("BUILD").Range("E4").Value = Sheets("DATA").Range("F" & i + 1).Value 'Home Team
Sheets("BUILD").Range("F4").Value = Sheets("DATA").Range("G" & i + 1).Value 'Away Team
Sheets("BUILD").Select
If i = Last_row Then
Range("A1").Value = 1
Else
Range("A1").Value = i + 1
Sheets("RESULTS").Range("A2" & i + 1).Value = Sheets("BUILD").Range("D4").Value 'League Name
Sheets("RESULTS").Range("B2" & i + 1).Value = Sheets("BUILD").Range("E4").Value 'Home Team
Sheets("RESULTS").Range("C2" & i + 1).Value = Sheets("BUILD").Range("F4").Value 'Away Team
End If
Application.ScreenUpdating = True
Sheets(sheet).Select
End Sub
I do not recommend using offset to counter the previous problem. Here are a few items corrected in the code:
Declare last row, column, etc as Long. There are over 1 million rows in Excel and integer will only handle up to 32,767. After that you will overload the value.
Shorten the workbook names by setting them as variables. No need to Dim as string.
Avoid Select and Activate by qualifying your worksheets and variables. That means giving as full information as needed to specify the location ThisWorkbook.Worksheets("Sheet1").Range("A1") versus Range("A1") that could be any sheet. Not only will this ensure proper locations, but will speed up your code by avoiding changing sheets.
Sub btn_NextMatch()
Application.ScreenUpdating = False
Application.Volatile
Dim Last_row As Long
Dim Last_Col As Long
Dim i As Long
Dim wks1 As Worksheet
Dim wks2 As Worksheet
Dim wks3 As Worksheet
Set wks1 = ThisWorkbook.Worksheets("BUILD")
Set wks2 = ThisWorkbook.Worksheets("DATA")
Set wks3 = ThisWorkbook.Worksheets("RESULTS")
i = wks1.Range("A1").Value
Last_row = wks2.Range("A" & Rows.Count).End(xlUp).Row
Last_Col = wks2.Cells.Find(What:="*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, LookIn:=xlValues).Column
Last_colletter = Split(wks2.Cells(1, Last_Col).Address, "$")(1)
If i = Last_row Then
i = 1
End If
wks1.Range("C2").Value = wks2.Range("C" & i + 1).Value 'MatchID
wks1.Range("D4").Value = wks2.Range("D" & i + 1).Value 'League Name
wks1.Range("E4").Value = wks2.Range("F" & i + 1).Value 'Home Team
wks1.Range("F4").Value = wks2.Range("G" & i + 1).Value 'Away Team
If i = Last_row Then
wks1.Range("A1").Value = 1
Else
wks1.Range("A1").Value = i + 1
wks3.Range("A" & i + 1).Value = wks1.Range("D4").Value 'League Name
wks3.Range("B" & i + 1).Value = wks1.Range("E4").Value 'Home Team
wks3.Range("C" & i + 1).Value = wks1.Range("F4").Value 'Away Team
End If
Application.ScreenUpdating = True
End sub
Darrel H. is right. If you are concatenating the iteration you're on to the cell address you are doing equivalent of: "A2" & 25 becomes A225, where you really wanted to have "A27". A way around this is to use the offset function. Your code rewritten would be like this:
Sheets("RESULTS").Range("A2" & i + 1).offset(rowoffset:=i + 1).value = Sheets("BUILD").Range("D4").Value 'League Name'
so i have Sheet1 that is use to contain the list of my inventory data. what i want to do is in another sheet(Sheet2). i can search my Sheet1 data and display the data there ( for example when i type cheetos, only the cheetos item got display ). Help me guys, using VBA is okay or other method is also fine.
If your results don't have to be on a different sheet, you could just convert your data to a Table. Select Cells A1:D8 and click on Insert -> Table. Make sure "My table has headers" is clicked and voila!
Once formatted as a table, you can filter Product ID however you need.
If you do need to show these results in another sheet, VBA would be my go-to solution. Maybe something like this:
Public Sub FilterResults()
Dim findText As String
Dim lastRow As Long
Dim foundRow As Long
Dim i As Long
'If there's nothing to search for, then just stop the sub
findText = LCase(Worksheets("Sheet2").Range("D4"))
If findText = "" Then Exit Sub
'Clear any old search results
lastRow = Worksheets("Sheet2").Cells(Rows.Count, 4).End(xlUp).Row
If lastRow > 5 Then
For i = 6 To lastRow
Worksheets("Sheet2").Range("C" & i).ClearContents
Worksheets("Sheet2").Range("D" & i).ClearContents
Worksheets("Sheet2").Range("E" & i).ClearContents
Worksheets("Sheet2").Range("F" & i).ClearContents
Next i
End If
'Start looking for new results
lastRow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
foundRow = 6
For i = 2 To lastRow
If InStr(1, LCase(Worksheets("Sheet1").Range("B" & i)), findText) <> 0 Then
Worksheets("Sheet2").Range("C" & foundRow) = Worksheets("Sheet1").Range("A" & i)
Worksheets("Sheet2").Range("D" & foundRow) = Worksheets("Sheet1").Range("B" & i)
Worksheets("Sheet2").Range("E" & foundRow) = Worksheets("Sheet1").Range("C" & i)
Worksheets("Sheet2").Range("F" & foundRow) = Worksheets("Sheet1").Range("D" & i)
foundRow = foundRow + 1
End If
Next i
'If no results were found, then open a pop-up that notifies the user
If foundRow = 6 Then MsgBox "No Results Found", vbCritical + vbOKOnly
End Sub
I would recommend avoiding VBA for this process as it can be done easily with excel's functions. If you would like to do it via VBA one could just loop through the list of products and find a key word, adding it to an array if the "Cheetos" is contained in the specific cell value using a wildcard like so:
This could be modified to run upon the change of the D4 cell if needed, and of course some modifications could be done to ensure that formatting etc can be done to your liking.
Sub test()
Dim wb As Workbook
Dim rng As Range, cell As Range
Dim s_key As String, s_find() As String
Dim i As Long
Set wb = Application.ThisWorkbook
Set rng = wb.Sheets("Sheet1").Range("B2:B8")
s_key = wb.Sheets("Sheet2").Range("D4").Value
wb.sheets("Sheet2").Range("C6:F9999").clearcontents
i = 0
For Each cell In rng
If cell.Value Like "*" & s_key & "*" Then
ReDim Preserve s_find(3, i)
s_find(0, i) = cell.Offset(0, -1).Value
s_find(1, i) = cell.Value
s_find(2, i) = cell.Offset(0, 1).Value
s_find(3, i) = cell.Offset(0, 2).Value
i = i + 1
End If
Next cell
wb.Sheets("Sheet2").Range("C6:F" & 5 + i).Value = Application.WorksheetFunction.Transpose(s_find)
End Sub
I need to create a VBA script in excel that chanages an order number from having "CD" at the front to "CD" at the end so from "CD00001" to "00001CD"
Any help would be awesome. all of the order numbers are in Column B and start at row 5. please help.
What i have so far:
Private Sub OrderNumber_Click()
Dim Val As String
Dim EndC As Integer
EndC = Worksheets("Raw Data Upload").Range("A1048576").End(xlUp).Row
For i = 5 To EndC
Val = Right("B" & i, Len("B" & i) - 2) & Left("B" & i, 2)
Range("B" & i).Value = Val
Next
End Sub
This replaces the order numbers with B5, B6 and so on but if i put this function into Excel itself it works fine.
Like this? DO you want it in column B?
Option Explicit
Private Sub OrderNumber_Click()
Dim i As Long
Dim val As String
Dim EndC As Long
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Raw Data Upload")
EndC = ws.Range("A1048576").End(xlUp).Row
For i = 5 To EndC
val = ws.Cells(i, "A")
Range("B" & i).Value = Mid$(val, 3, Len(val) - 2) & Left$(val, 2)
Next i
End Sub
dim beginStr, endStr, originalStr, outputStr as string
dim rng as range
'put the below into a loop, assigning a rng to the desired cell each time
originalStr = rng.value ' Change to chosen range
beginStr = left(originalStr,2)
endStr = right(originalStr, len(originalStr) - 2)
outputStr = endStr + beginStr
Range("B" & i).Value = outputStr
I haven't got a copy of Excel to test this on but it should work.
Simply use:
Right(Range("B" & i), Len(Range("B" & i)) - 2) & Left(Range("B" & i), 2)
An alternative is to set up the cell as a Range():
Sub t()
Dim cel As Range
Dim endC As Long
endC = Worksheets("Raw Data Upload").Range("A1048576").End(xlUp).Row
For i = 5 To endC
Set cel = Range("B" & i)
myVal = Right(cel, Len(cel) - 2) & Left(cel, 2)
Range("B" & i).Value = myVal
Next
End Sub
Currently, when you do Right("B" & i, Len("B" & i) - 2) & Left("B" & i, 2), for row 5, this becomes Right("B5", Len("B5") - 2) & Left("B5", 2) then this evaluates to simply:
Right("B5",0) & Left("B5",2), which is
[nothing] & B5, finally becoming
B5
Note the lack of using B5as a range. Instead it's being treated as a string.
(Also, I'm assuming this is to be run on the ActiveSheet. If not, please add the worksheet before the range, i.e. Worksheets("Raw Data Upload").Range("B" & i)...)
Try this
Private Sub OrderNumber_Click()
Dim cell As Range
With Worksheets("Raw Data Upload")
For Each cell in .Range("B5", .Cells(.Rows.Count, 2).End(xlUp))
cell.Value = Right(cell.Value, Len(cell.Value) - 2) & Left(cell.Value, 2)
Next
End With
End Sub