If condition is met copy cell.values in one row - vba

I'm sorry but I asked this question already yesterday, but it seems like I wasn't clear enough with my wishes, so I try it again this time.
My code Looks like this right now:
If OptionButton11.Value = True Then
Set Rng = Sheets("Table").Range(TextBox3.Value & TextBox1.Value + 1 & ":" & TextBox3.Value & lastrow)
Set kst = Sheets("Table").Range(TextBox2.Value & TextBox1.Value + 1 & ":" & TextBox2.Value & lastrow)
For Each Cell In Rng
If Cell.Value = TextBox10.Value Then
Cell.copy Cell.Offset(, 1)
Cells(1, Columns.Count).End(xlToLeft).Offset(, 1) = kst.Value
End If
Next Cell
End If
In this scenario, the user has the opportunity to use textboxes to define where his values are in the worksheet and what the macro has to look for.
Textbox1.Value defines where the headings in the worksheet are.
`
Textbox2.Value defines where the value can be found
Textbox3.Value is the criteria after the value is filtered
And
Textbox.Value 4 is the required criteria.
I would like to achieve with this code; that whenever Textbox4.Value is found in the range of Textbox3.Value, TextBox2.Value and Textbox3.Value are copied into the first free columns in the worksheet.
My Problem right now is, that
Cells(1, Columns.Count).End(xlToLeft).Offset(, 1) = kst.Value
do not copy the values in the first empty column, but add them horizontally to each freely available row in a column.
I already tried it with xlDown instead of xlToLeft but then a runtimerror (1004) appears.
Has anyone a suggestion how to fix this?
Thank you.

Related

Excel VBA - Making a Named Range based on a found cell

I am trying to figure out how to make a named range, based on a cell found using:
For Each Cell In ISBN_Range
If Cell.Value = ISBN Then
ISBN_Valid = True
ISBN_Found = Range("A" & Cell.RowIndex & ":E" & Cell.RowIndex)
ISBN_Found.Interior.ColorIndex = 6
Exit For
End If
Next Cell
This is not working, and I am not sure why, I haven't been able to find the answer elsewhere, sorry if this is really simple! I basically just want to make the row of data that the found cell exists in a named range. ISBN_Found is declared as a range much earlier in my code, so that is not the issue.
I figured out the answer with some help from the guys in the comments, final code looks like this:
For Each Cell In ISBN_Range
If Cell.Value = ISBN Then
ISBN_Valid = True
Set ISBN_Found = Range("A" & Cell.Row & ":E" & Cell.Row)
ISBN_Found.Interior.ColorIndex = 6
Exit For
End If
Next Cell
Just needed to delete "Index" from "Cell.RowIndex"

Using VBA If then statement to copy and paste data with TextBox.Values

I am currently facing the following problem:
The source data currently looks as follows:
Value#1 Value#2
10 AA
11 AA
12 AB
13 AD
1231 AA
125 AB
4312 AA
12314 AA
Now the user has multiple userform textboxes where he can define where the respective values ​​are:
Textbox1 = defines the beginning row of the values
Textbox2 = Column for Value#1
Textbox3 = Column for Value#2
Textbox4 = Criteria in Value#2
Now I want to achieve the following; the user should specify where his values#1 are (in TextBox2), then he should define the column in which the criteria can be found (Values#2 in TextBox3), and after that he should define what criteria should be filtered.
So if he chooses to type "AB" in Textbox4 then the following has to appear in the first available columns in the worksheet:
Value#1 Value#2
12 AB
125 AB
My current code looks something like this, but I'm constantly changing it and nothing really works (syntax-error). I'm actually sure that the beginning of the Syntax is kinda allright (?), but I've no idea how to express with vba that I want them to copy the value from the column into another one, if the criteria is matched. There are plenty of examples on here and at other places, but I couldn't find anything where the range or value isn't predefined.
Dim c as Range
If OptionButton1.Value = True Then 'also this only happens if the user decides that an Optionbutton is true
For Each c In Sheets ("Table") Range (TextBox3.Value & TextBox1.Value + 1 & ":" & TextBox3.Value & lastrow)
If cell.Value = TextBox4.Value Then
Range (TextBox2.Value & TextBox1.Value + 1 & ":" & TextBox2.Value & lastrow) c.copy c.Offset (, 1) 'syntax-error
End If
Next
End If
I'm pretty new to VBA and programming as a whole and can't find a solution to this.
Through some research I'm pretty sure that the syntax to solve this problem is kinda like "For each "x"" etc. but I've never found something where the range und the value is defined with a TextBox.
A few notes regarding your code:
First, you are looping with C in the line For Each c In Sheets ("Table")..., but the following line you are checking If cell.Value = TextBox4.Value, instead of If C.Value = TextBox4.Value.
Second, if you want to copy that cell in case it's equal to TextBox4.Value to the next column, use C.Copy C.Offset(, 1).
Try the code below:
Dim Rng As Range
Dim C As Range
If OptionButton1.Value = True Then 'also this only happens if the user decides that an Optionbutton is true
' set the range fisrt , See if you are getting the Error on this line -->
Set Rng = Sheets("Table").Range(TextBox3.Value & TextBox1.Value + 1 & ":" & TextBox3.Value & lastrow)
For Each C In Rng
' for DEBUG ONLY
Debug.Print C.Value & " | TextBox4 value: " & TextBox4.Value
If C.Value = TextBox4.Value Then
MsgBox "There is a match" ' <-- for DEBUG ONLY
C.Copy C.Offset(, 1) ' copy the value from the cell into the next column to the right
End If
Next C
End If

Excel VBA range select

I have a macro in which I need to select the range R2:last row in sheet. However the last row in my sheet might be blank in column R. At the moment I am using this
Dim t As Range
Set t = Range("R2", Range("R1000").End(xlUp))
For Each Cell In t
If IsEmpty(Cell) Then
Cell.Activate
ActiveCell.Value = "To Be Picked Up"
End If
Next
However if the last row has a blank in column R then it gets ignored. I am hoping to pull the range using column A, as the last row of data always has column A. So something like,
Dim t As Range
Set t = Range("R2", Range("A1000").End(xlUp).ActiveCell.Offset(0, 17))
For Each Cell In t
If IsEmpty(Cell) Then
Cell.Activate
ActiveCell.Value = "To Be Picked Up"
End If
Next
It seems so simple but I'm sure im missing something stupid. Any help or alternative methods would be helpful thank you.
This should do the trick in one line:
Sub SO()
Range("R2:R" & Range("A" & Rows.Count).End(xlUp).Row).SpecialCells(xlCellTypeBlanks).Value = "To Be Picked Up"
End Sub
But in answer to your question specifically
Set t = Range("R2:R" & Range("A" & Rows.Count).End(xlUp).Row)
The Range() method will accept a string as an argument to obtain a range.So we can build this string any way we want:
"A1000" '// A1000
"A" & 1000 '// A1000
"A" & "10" & "00" '// A1000
"A" & CStr(1001 - 1) '// A1000
"A" & Rows.Count will return A65536 or A1048576 depending on the type of worksheet.
Range("A1048576").End(xlUp) as you know, will retrieve the last cell in that area, or the first cell in the next area on the direction specified.
Range("A1048576").End(xlUp).Row will return the row number of that cell (let's say it's A1000 for argument's sake) so the return value is 1000.
"R2:R" & Range("A" & Rows.Count).End(xlUp).Row therefore makes the string R2:R1000.
So finally, Range("R2:R" & Range("A" & Rows.Count).End(xlUp).Row) is the same as Range("R2:R1000")

Moving a Do Until function across columns in excel vba

I'm pretty new to VBA and having trouble creating a quick macro used to move blocks of numbers around.
What I am trying to create is a button that when pressed:
Moves the contents of (i,5) to E63
The cells from (i, 16) down to F67:F110
Dependant on whether Row 10 contains "Low" or "High" moves three cells from the set
N106:N109 to the cells (i12:i14) [Where i is the column reference).
The Range sections of code are what accomplish this and they are working fine, the problem I am having is with my Do.Until row and with the reference Column(i)
Does anyone know how this could work? Thanks
UPDATE
So thanks to the help of Siddharth I've been able to fix all but one bit, which is the lines where there is a string in the Range function. The reason I am not using .Formula here but Paste instead is that otherwise all of the cells A12:A14 to Z12:Z14 will equal the same thing which isn't correct. On the other parts that doesn't matter. I am getting a type 13 mismatch error on these lines.
Sub Columntest()
Dim i As Integer
i = 5
Do Until Cells(5, i).Value = ""
If Cells(10, i).Value = "Low" Then
Range("E63").Formula = Cells(5, i)
Range("F67:F110").Formula = Cells(16, i)
Range("O106:O108").Copy
Range("=" & Columns(i) & "12").PasteSpecial Paste:=xlPasteValues
End If
If Cells(10, i).Value = "High" Then
Range("E63").Formula = Cells(5, i)
Range("F67:F110").Formula = Cells(16, i)
Range("N106:N108").Copy
Range(Columns(i) & "12").PasteSpecial Paste:=xlPasteValues
End If
i = i + 1
Loop
End Sub
The type mismatch is because you are trying to concatenate a column object and a string in the range reference:
Range("=" & Columns(i) & "12").PasteSpecial Paste:=xlPasteValues
Try using this instead:
Cells(12, i).PasteSpecial Paste:=xlPasteValues

Entering Data into a spreadsheet through a UserForm in Excel

I am new to VBA in Excel, and I have a basic userform which is to place the data into the sheet. the data from the form is to enter in cell B13 through to G13, then every other entry after should be done on the next row down e.g. B14-G14.
I have this code already however it isnt entering the data into the correct cell and is repeatedly entering it on the same row...
Private Sub CommandButton1_Click()
Dim lngWriteRow As Long
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
lngWriteRow = ws.Cells(Rows.Count, 1) _
.End(xlUp).Offset(1, 0).Row
If lngWriteRow < 13 Then lngWriteRow = 13
ws.Range("B" & lngWriteRow) = TextBox1.Value
ws.Range("C" & lngWriteRow) = TextBox2.Value
ws.Range("D" & lngWriteRow) = TextBox3.Value
ws.Range("E" & lngWriteRow) = ComboBox1.Value
ws.Range("F" & lngWriteRow) = TextBox4.Value
ws.Range("G" & lngWriteRow) = ComboBox2.Value
End Sub
How would i achieve this? (There is already data on the rows below)
Thanks in advance
This line here is wrong:
lngWriteRow = ws.Cells(Rows.Count, 12) _
.End(xlUp).Offset(1, 0).Row
Because you are referring to column 12, which you do not alter - hence the row stays the same.
Use this instead
lngWriteRow = ws.Cells(Rows.Count, 2) _
.End(xlUp).Offset(1, 0).Row
Edit:
If you want an initial offset, to start the data-input # row 13, use this:
lngWriteRow = ws.Cells(Rows.Count, 2) _
.End(xlUp).Offset(1, 0).Row
if lngWriteRow < 13 then lngWriteRow = 13
You cannot use Offset(12,0), because you would use it everytime!
Edit
Just to be crystal clear, this here works on an empty sheet, when pasting the code as a worksheet-macro and hitting F5 multiple times. So, unless there is explained, what this does wrong, I consider the question solved.
Private Sub Test()
Dim lngWriteRow As Long
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
lngWriteRow = ws.Cells(Rows.Count, 2) _
.End(xlUp).Offset(1, 0).Row
If lngWriteRow < 13 Then lngWriteRow = 13
ws.Range("B" & lngWriteRow) = "test"
ws.Range("C" & lngWriteRow) = "test"
ws.Range("D" & lngWriteRow) = "test"
ws.Range("E" & lngWriteRow) = "test"
ws.Range("F" & lngWriteRow) = "test"
ws.Range("G" & lngWriteRow) = "test"
End Sub
Edit
After some mailing, here is the solution to this riddle: it was not stated, that there are filled cells beneath those, which shall be entered.
So for col-B it was more like
title-row
row13
row..
row..
row63
space
other stuff
basically the suggested corrections worked - but they looked for the last filled cell in column B on the whole sheet, which was the problem.
Here is the solution to that:
lngWriteRow = ws.Cells(ws.Range("B12:B63")Rows.Count, 2) _
.End(xlUp).Offset(1, 0).Row
And to give you some explanaition on the way:
You can't use (Rows.Count,1) instead of (Rows.Count,2), because you are adding Data in the columns B-G, which is 2-7. You have to use 2-7 because of the way, you are looking for the last row. If you use 1, you're looking for the last value in column A, which does not change, when you are trying to add new data.
You can't use Offset(12,0), because this would create an offset everytime you insert data - so you would end up with rows 12 rows apart.
And finally, you can't use Rows.Count, because this is 65536 or so, and you have data beneath the data you are adding. End(xlUp) will lookup from too far down, and stop at the last cell of column B, which has data in it - but this won't be B13, unless there is no data in B14-B65536.
Hope this helps to understand the dynamics here.