Fill data from userform to next row - excel

I have made a userform, but I can't manage to fill the data from it to the next row every time, it always fills the same row.
Here is my current code:
Private Sub btnivesti_Click()
Dim ssheet As Worksheet
Set ssheet = ThisWorkbook.Sheets("Lapas1")
ssheet.Cells(3) = CDate(Me.tddate)
ssheet.Cells(1) = Me.cmblistitem
ssheet.Cells(4) = Me.tbpo
ssheet.Cells(6) = Me.tbkodas
ssheet.Cells(8) = Me.tbkiekis
End Sub
Private Sub UserForm_Initialize()
Me.tddate = Date
'fill drop box
For Each cell In [listas1]
Me.cmblistitem.AddItem cell
Next cell
End Sub

Your current code references the cell number. Cell number determines cell location by counting the number of cells individually (Row 1 would have cell numbers from 1 to 16384, Row 2 from 16385 to 32768, etc.), which is highly inefficient. Instead, you should reference the row and column where you want to put your data.
Since you want to fill new data to new rows, get the location of the last row with data on it and increment by 1. Try this:
Private Sub btnivesti_Click()
Dim ssheet As Worksheet
Dim lastrow as Integer
Set ssheet = ThisWorkbook.Sheets("Lapas1")
lastrow = Range("A" & Rows.Count).End(xlUp).Row + 1
ssheet.Cells(lastrow, 3) = CDate(Me.tddate)
ssheet.Cells(lastrow, 1) = Me.cmblistitem
ssheet.Cells(lastrow, 4) = Me.tbpo
ssheet.Cells(lastrow, 6) = Me.tbkodas
ssheet.Cells(lastrow, 8) = Me.tbkiekis
End Sub

Related

Copy values from cells in range and paste them in random cell in range

I have two ranges as showed in this picture.
I'm trying to write a VBA macro that successively selects a single cell in the first range (“B23, F27”) , copies the selected cell's value, then selects a random cell in the second range (“G23, K27”), and pastes the first cell's value into the randomly selected cell in the second range.
This should repeat until every cell from the first range has been copied, or every cell in the second range is filled with a new value. In this example both outcomes are equivalent as both ranges have the same number of cells (25).
The result should be like the second image.
I tried to assign the first range to an array and then pick a random value from this array and paste it to the second range.
I also tried to extract unique values from the first range, build a dictionary with it then pick a random cell from the second range and a random value from the dictionary and paste it.
Later I tried again using the VBA syntax “with range” and f"or each cell in range" but I can’t just come up with something that actually works. Sometimes the second range is filled by various values, but not as intended.
First example: this one just does not work
Sub fillrange()
Dim empty As Boolean
'This part checks if every cell in the first range as a value in it
For Each Cell In Range("B23", "F27")
If Cell.Value = "" Then
empty = True
End If
Next
'If every cell is filled then
If empty Then
Exit Sub
Else:
With ThisWorkbook.Worksheets("Sheet1)").Range("B23", "F27")
.Cells(Application.WorksheetFunction.RandBetween(1, 25)).Select
.Copy 'the cell select works, but it will copy all range
'This does not work
'For Each Cell In Range("G23", "K27")
'Cells(Application.WorksheetFunction.RandBetween(1, 25)).Select
'.PasteSpecial Paste:=xlPasteValues
'Next
End With
End If
End Sub
Second example: it fills the range but with wrong values
Sub fillrange2()
Dim empty As Boolean
For Each cell In Range("B23", "F27")
If cell.Value = "" Then
empty = True
'This part checks if every cell in the first range as a value in it
Exit For
End If
Next cell
If empty Then
Exit Sub
Else:
Dim ws As Worksheet
Dim lRow As Long, i As Long
Dim col As New Collection, itm As Variant
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 1 To lRow
On Error Resume Next
col.Add .Range("B23", "F27").Value, CStr(.Range("A" & i).Value)
On Error GoTo 0
Next i
End With
Dim MyAr() As Variant
ReDim MyAr(0 To (col.Count - 1))
For i = 1 To col.Count
MyAr(i - 1) = col.Item(i)
Next
For Each cell In Range("G23", "K27")
cell.Value = Application.WorksheetFunction.RandBetween(LBound(MyAr), UBound(MyAr))
Next
End If
End Sub
Third example: as the second example, it fills the range but with wrong values
Sub fillrange3()
Dim MyAr() As Variant
MyAr = Range("B23", "F27")
For Each cell In Range("G23", "K27")
cell.Value = Application.WorksheetFunction.RandBetween(LBound(MyAr), UBound(MyAr))
Next
End Sub
Maybe something like this ?
Sub test()
Set Rng = Range("G23:K27")
n = 1
totCell = 25
Set oFill = Range("G23")
Set oSource = Range("B23")
For i = 1 To 5
oFill.Value = "X" & n
oFill.AutoFill Destination:=Range(oFill, oFill.Offset(4, 0)), Type:=xlFillSeries
Set oFill = oFill.Offset(0, 1)
n = n + 5
Next i
For i = 1 To 5
Do
RndVal = Int((totCell - 1 + 1) * Rnd + 1)
xVal = "X" & RndVal
Set C = Rng.Find(xVal, lookat:=xlWhole)
If Not C Is Nothing Then
C.Value = oSource.Value
Set oSource = oSource.Offset(1, 0)
check = check + 1
If check = 5 Then Exit Do
End If
Loop
Set oSource = oSource.Offset(-5, 1)
check = 0
Next i
End Sub
I cheat by making a preparation for the range G23 to K27 fill with X1 to X25 in the first for i = 1 to 5.
The second for i = 1 to 5 is to offset from column B to G.
The Do - Loop is to generate random number between 1 to 25.
If the generated number is found then the found cell has the value from the "source",
if not found, it loop until the generated number is found 5 times (hence also the found cell is fill with 5 different source). Then before the next i, the "source" cell is offset to the next column.
This if I'm not wrong to get what you mean.
Here's another approach, just for a bit of variety.
Sub x()
Dim r1 As Range, r2 As Range, i As Long
Dim r As Long, c As Long
Set r1 = Range("B23").Resize(5, 5) 'define our two ranges
Set r2 = Range("G23").Resize(5, 5)
r2.ClearContents 'clear output range
With WorksheetFunction
Do Until .Count(r2) = r2.Count 'loop until output range filled
r = .RandBetween(1, 25) 'random output cell number
If .CountIf(r2, r1.Cells(i)) = 0 Then 'if not in output range already
If r2.Cells(r) = vbNullString Then 'if random cell empty
r2.Cells(r).Value = r1.Cells(i).Value 'transfer value
i = i + 1
End If
End If
Loop
End With
End Sub

Excel VBA code for matching values and copying whole row

So I am extremely new to VBA but have to finish a project that requires sorting some data. I have two sheets. One sheet( called 'values') has a single column of values that I need to test if a value matches at least one of the 5 columns of a record (row) in another very large sheet ('sheet1'), and copy the whole record (row) to a second spreadsheet ('sheet2).
This is my pseudo code:
for each row in sheet1 where sheet1.row = A1:Q1231231
for each value in values where values.value = b1:b300
for each col (e1:j1) where sheet1.col = E-rownum : J-rownum
if value == col-value
copy row to sheet2
break, esc value
Next row
And this is what i have so far, but i'm a little stuck on whether im referencing everything correctly. How do i just obtain columns E:J for each row when I need to match the values against those cells only? How do I copy the entire row if there is a match, and to immediately break and move on to the next record?
Private Sub CommandButton1_Click()
Dim sheetrow As Range
Dim Values As Range
Dim cells As Range
Set Sheet1 = Worksheets("Sheet1")
Set Values = Worksheets("values").Rows("B2:B330")
Set Sheet2 = Worksheets("Sheet2")
For Each sheetrow In Sheet1.Rows
For Each value In Values
For Each cell In sheetrow.cells // only need cell cols E:J
//if value == cell
// copy row to sheet2
//break (no need to check the rest of the row if match)
Next
Next
Next
End Sub
Just to inform, this is not for a VBA assignment. This is just a very large amount of data and a script would work better than trying to manually go through it. Thank you so much!
Your pseudo-code looks good, I did remove the 3rd loop though, albeit you could certainly loop through the columns.
Is this what you are looking for?
Option Explicit
Sub Test()
Dim i As Long
Dim j As Long
Dim rngValues As Range
Dim rng As Range
Dim Sheet1 As Worksheet
Dim Sheet2 As Worksheet
Application.ScreenUpdating = False 'Turns of Screenupdating to let the code run faster
Set Sheet1 = ThisWorkbook.Sheets("Sheet1")
Set Sheet2 = ThisWorkbook.Sheets("Sheet2")
Set rngValues = ThisWorkbook.Sheets("Values").Range("B2:B330")
j = 1 'counter to count up the rows on the destination sheet
For i = 1 To Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp).Row 'determines the last row on Sheet1
For Each rng In rngValues
'default return value of range is the value in it, so there would be no need to use range.value
' _ continues the code in the next line for readability
If Sheet1.Cells(i, 5).Value = rng.Value or Sheet1.Cells(i, 6).Value = rng.Value Or Sheet1.Cells(i, 7).Value = rng.Value or _
Sheet1.Cells(i, 8).Value = rng.Value or Sheet1.Cells(i, 9).Value = rng.Value Or Sheet1.Cells(i, 10).Value = rng.Value Then
'This copies the entire row an parses it to destination
Sheet1.Cells(i, 1).EntireRow.Copy Destination:=Sheet2.Cells(j, 1)
j = j + 1
End If
Next
Next
Application.ScreenUpdating = True
End Sub
I'm not sure if I understood your question correctly though.

VBA - Delete all rows that do not contain at least 1 highlighted cell

Looking for VBA code to delete all rows that do not contain at least 1 highlighted cell (interior color used: REDINDEX).
Sample data sheet with randomly highlighted cells
you can do it like this:
Public Sub DeleteAllRowsWithNoHighlitedCells()
Dim iRow As Long
Dim lastColumn As Long
Dim aktRow As Range
Dim owsh As Worksheet
Set owsh = ActiveSheet
iRow = 1
lastColumn = 7
Do Until owsh.Cells(iRow, 1) = ""
Set aktRow = owsh.Range(Cells(iRow, 1), Cells(iRow, lastColumn))
If Not AktRowHasHighlightedCells(aktRow) Then
owsh.Rows(aktRow.Row).Delete
iRow = iRow - 1
End If
iRow = iRow + 1
Loop
End Sub
Private Function AktRowHasHighlightedCells(ByVal aktRow As Range) As Boolean
Dim aktcell As Variant
For Each aktcell In aktRow.Cells
If aktcell.Interior.ColorIndex = 3 Then
AktRowHasHighlightedCells = True
Exit Function
End If
Next aktcell
AktRowHasHighlightedCells = False
End Function
To explain what i mean. First you have to create a Button and put the DeleteAllRowsWithNoHiglitedCells - Procedure behind the Click-Event. Then until Column1 for each row is not empty, every Cell in the selected Row from column1 to lastColumn (you have to define or you also can get the lastusedColumn via VBA) is checked for a Interior.Colorindex = 3 (hard coded red) If the Function AktRowHasHighlightedCells is false, the row will be deleted and the rowCounter will be decreased.

How do you add a variable.value as the parameter of range()?

I'm trying to merge the first three empty rows and write Activity# in the three merged cells. I can't even figure out how to select 3 custom cells to get them ready for merging. I checked everywhere online but range(A1:B2) is always given a definitive range. How do I write for example: range(variable_A1:variable_B2)?
This is my code so far:
Private Sub OKButton_Click()
'Make Sheet1 active
Sheet1.Activate
Dim beginning
Dim ending
Dim selection
beginning = Cells(empty_row.Value, 2)
ending = Cells(empty_row.Value + 2, 2)
'this is supposed to select 3 cells, but it doesn't work
selection = Range("beginning:ending").Select
'figure out how to merge cells below
Cells(empty_row.Value, 2).Value = "Activity" & Activity_number.Value
Dim i As Integer
For i = 1 To nb_subs.Value
Cells(empty_row.Value + i + 2, 2).Value = "Sub-Activity" & i
Next i
Private Sub OKButton_Click()
Dim beginning As Range
Dim ending As Range
Dim selection As Range
With Sheet1
Set beginning = .Cells(empty_row.Value, 2)
Set ending = .Cells(empty_row.Value + 2, 2)
'this is supposed to select 3 cells, but it doesn't work
Set selection = .Range(beginning, ending)
selection.Merge
selection.Value = "Activity" & Activity_number.Value
Dim i As Integer
For i = 1 To nb_subs.Value
.Cells(empty_row.Value + i + 2, 2).Value = "Sub-Activity" & i
Next i
End With

Excel: Return If result of same Cell in different Sheets

I have different Sheets in the same Workbook with the same pattern and same tables. I need to check for a cell value in these sheets to evaluate for a condition and return its values.
For Example: Cell B2 in Sheet1 through Sheet9 is always a number, in another sheet I need to know which of these numbers are Less than 5. Then return an array with the values.
Here is a solution in VBA. Edit the lines that I call out at the top of the macro.
Option Explicit
Sub get_from_sheets()
Dim cell_values(), threshold As Double
Dim source_cell, output_first_cell, output_sheet As String
Dim num_sheets, start_sheet, end_sheet, a As Integer
Dim out_rw, out_cl As Integer
source_cell = "B2" 'fill in this
start_sheet = 10 'fill this
end_sheet = 13 'fill this
output_sheet = "Sheet14" 'fill this
output_first_cell = "A1" 'fill this
threshold = 5 'fill this
out_rw = Range(output_first_cell).Row
out_cl = Range(output_first_cell).Column
ReDim cell_values(end_sheet)
For a = start_sheet To end_sheet
cell_values(a) = Sheets("Sheet" & a).Range(source_cell)
Next a
For a = start_sheet To end_sheet
If cell_values(a) < threshold Then
Sheets(output_sheet).Range(Cells(out_rw, out_cl), Cells(out_rw, out_cl)) = cell_values(a)
out_rw = out_rw + 1
End If
Next a
End Sub

Resources