Add value from combobox onto multiple columns - excel

I have created a combobox that has different cases seen below. The current formula works except that I would like to add a additional column that replicates the same value given to columns C and want to add it column R.
Ex. ComboBox
Select Current Month
I want to add 500 units to Column C and Column R based on the part that was searched for.
Private Sub cmdAdd_Click()
Dim irow As Long
Dim lastRow As Long
Dim iCol As String
Dim C As Range
Dim ws As Worksheet
Dim value As Long
Dim NewPart As Boolean
Set ws = Worksheets("Summary")
Set C = ws.Range("A7:A1048576").Find(What:=Me.PartTextBox.value, SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues, LookAt:=xlWhole)
If C Is Nothing Then
'find first empty row in database
lastRow = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count
irow = lastRow + 1
NewPart = True
Else
'find row where the part is
irow = ws.Cells.Find(What:=Me.PartTextBox.value, SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row
NewPart = False
End If
'check for a part number
If Trim(Me.PartTextBox.value) = "" Then
Me.PartTextBox.SetFocus
MsgBox "Please Enter A Part Number"
Exit Sub
End If
If Trim(Me.MonthComboBox.value) = "" Then
Me.MonthComboBox.SetFocus
MsgBox "Please Enter A Month"
Exit Sub
End If
If Trim(Me.AddTextBox.value) = "" Then
Me.AddTextBox.SetFocus
MsgBox "Please Enter A Value To Add Or Substract"
Exit Sub
End If
Select Case MonthComboBox.value
Case "Current Month"
iCol = "C" And "R"
Case "Current Month +1"
iCol = "N"
Case "Current Month +2"
iCol = "O"
Case "Current Month +3"
iCol = "P"
Case "Current Month +4"
iCol = "Q"
End Select
value = Cells(irow, iCol).value
With ws
.Cells(irow, iCol).value = value + CLng(Me.AddTextBox.value)
End With
If NewPart = True Then
ws.Cells(irow, "A").value = Me.PartTextBox.value
End If
If NewPart = True Then
ws.Cells(irow, "C").value = Me.AddTextBox.value
End If

I may recommend using an Array to store the columns.
Sub t()
Dim iCol()
Dim testStr$, myValue$
Dim iRow&
Dim ws As Worksheet
testStr = "Current Month"
Select Case testStr
Case "Current Month"
iCol() = Array("C", "R")
Case "Current Month +1"
iCol() = Array("N")
End Select
Dim i&
For i = LBound(iCol) To UBound(iCol)
myValue = Cells(iRow, iCol(i)).value ' WHAT SHEET IS THIS ON??
With ws
.Cells(iRow, iCol(i)).value = myValue + CLng(Me.AddTextbox.value)
End With
Next i
End Sub
You can add to the Case as needed. Note that you need to wrap the Next i after you're done working with a column, so it can see if there's a second one to run on.
Also, since you didn't include all the code, you may have to adjust the ranges. (note the myValue doesn't have a Sheet specified for what Cells() to use).

Related

Search words in two columns and copy to another sheet

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.

How to create a textjoin worksheet function with dynamic range

I have data where I have many column headers. One of the header is "Text" and one other header is "Value Date". I want to combine the values contained in every row between these columns in another column row-wise.
The problem is the number of columns between these two headers is not constant. It changes with every new ledger I export. So I want my code to be dynamic in such a way that it will identify the column of "Text" and then it will identify the column of "Value Date" and combine everything between in another column row-wise.
This is where I have reached with my code but I don't know why it's not working. I have been trying this for last 3 days only to get nowhere. When I run this code, the result which I get is "TextColumnNo:ValueColumnNo".
Sub TextJoin()
Dim TextColumnNo As Range
Dim ValueColumnNo As Range
Range("A1").Select
ActiveCell.EntireRow.Find("Text").Activate
Set TextColumnNo = Range(ActiveCell.Address(False, False))
Range("A1").Select
ActiveCell.EntireRow.Find("Value").Activate
Set ValueColumnNo = Range(ActiveCell.Address(False, False))
ActiveCell.Offset(1, -1).Select
Application.CutCopyMode = False
ActiveCell.Value = Application.WorksheetFunction.TextJoin(" ", True, _
"TextColumnNo:ValueColumnNo")
ActiveCell.Select
Selection.AutoFill Destination:=ActiveCell.Range("A1:A8524")
ActiveCell.Range("A1:A8524").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End Sub
You would need 2 loops for this. One looping through all rows and one looping through the columns to combine the text for each row.
Note that you need to adjust some things like sheet name and output column here.
Option Explicit
Public Sub TextJoin()
Dim ws As Worksheet
Set ws = Worksheets("Sheet1") 'define a worksheet
'find start
Dim FindStart As Range
Set FindStart = ws.Rows(1).Find("Text")
If FindStart Is Nothing Then
MsgBox "start not found"
Exit Sub
End If
'find end
Dim FindEnd As Range
Set FindEnd = ws.Rows(1).Find("Value Date")
If FindEnd Is Nothing Then
MsgBox "start not found"
Exit Sub
End If
'find last used row in column A
Dim lRow As Long
lRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim iRow As Long
For iRow = 2 To lRow 'loop through all rows (2 to last used row)
Dim CombinedText As String
CombinedText = vbNullString 'initialize/reset variable
Dim iCol As Long 'loop through columns for each row (from start to end column)
For iCol = FindStart.Column To FindEnd.Column
CombinedText = CombinedText & ":" & ws.Cells(iRow, iCol).Text 'combine values
Next iCol
ws.Range("Z" & iRow) = CombinedText 'write values in column Z
Next iRow
End Sub
Sub TextJoin()
Dim ColRefText As Long
Dim ColRefValueDate As Long
Const firstcol = "Text"
Const secondcol = "Value Date"
Dim r As Range
Set r = Rows(1).Cells.Find(firstcol)
If Not r Is Nothing Then
ColRefText = r.Column
Set r = Rows(1).Cells.Find(secondcol)
If Not r Is Nothing Then
ColRefValueDate = r.Column
End If
End If
If ColRefValueDate + ColRefText > 0 Then
With Cells(2, Worksheets(1).Columns.Count).End(xlToLeft).Offset(0, 1)
.Formula = Replace("=" & Cells(2, ColRefText).AddressLocal & "&" & Cells(2, ColRefValueDate).AddressLocal, "$", "")
.Copy Range(.Address, Cells(ActiveSheet.UsedRange.Rows.Count, .Column).Address)
End With
End If
End Sub

Adding value when certain condition applies

I'm interested in a macro that will add a value in column P (Pass, At Risk or Failed) if column A has a certain condition - see below example.
I wonder if below macro can be used as inspiration. It was created to color a row if certain condition is met.
I'd also like the new macro to assign certain cell color in column P for value: Green for Pass, Yellow for At Risk and Red for Failed (same colors as in below macro)
Option Explicit
Sub Stackoverflow()
Dim ws As Worksheet
Dim rows As Long, i As Long
Dim rngSearch As Range, rngColor As Range
Application.ScreenUpdating = False
Application.EnableEvents = False
Set ws = ActiveSheet
rows = ws.UsedRange.rows.Count
For i = 1 To rows
Set rngSearch = ws.Cells(i, 1)
Set rngColor = ws.Range("A" & i, "O" & i)
If rngSearch = "Unexpected Status" Then
rngColor.Interior.Color = 13434828
End If
If rngSearch = "At Risk" Then
rngColor.Interior.Color = 8420607
End If
If rngSearch = "Requirements Definition" Then
rngColor.Interior.Color = 10092543
End If
Next i
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
This would make column P yellow, if rngSearch is "At Risk":
For i = 1 To rows
Set rngSearch = ws.Cells(i, 1)
Set rngColor = ws.Range("A" & i, "O" & i)
If rngSearch = "Unexpected Status" Then
rngColor.Interior.Color = 13434828
End If
If rngSearch = "At Risk" Then
Cells(rows, "P").Interior.Color = vbYellow
End If
If rngSearch = "Requirements Definition" Then
rngColor.Interior.Color = 10092543
End If
Next i
The others are to be made correspondingly.
Yes you can, simplified
Dim i As Long, lngColor as Long 'It is inadvisable to declare variables which could also be the name of built in functions and objects, in your case I would not declare "rows" as a variable as it is also a property of an object
Dim varVal as Variant
Dim ws As Worksheet
Set ws = Thisworkbook.Worksheets("Sheet1") 'As general advice, avoid active and select but used fixed values, this way no confusion can exist as to which sheet is used In my example it is Sheet1, but you have to set it to the actual name of your sheet
with ws
For i = 1 To .UsedRange.Rows.Count
Select Case .Cells(i, 1) 'Looks at the value of row i column A, and then below if it matches a case.
Case "Unexpected Status"
varVal = "Pass"
lngColor = 13434828
Case "At Risk"
varVal = "At Risk"
lngColor = 8420607
Case "Requirements Definition"
varVal = "Failed"
lngColor = 10092543
Case else
varVal = Empty
lngColor = 0
End Select
.Cells(i, 16) = varVal 'row i in column P is set to the value determined by the condition in the select case part
If Not lngColor = 0 Then 'This value of lngColor is only present if the select case did not match and if so, the color should not be changed
.Range(.Cells(i, 1), .Cells(i, 16)).Interior.Color = lngColor 'Set the range of row i column A to column P to the color specified by the case select.
End If
Next i
End With

VBA Excel remove Items unique to one sheet

I'm working on a long application and I hit a wall trying to find unique records between 2 sheets and removing the row from the first sheet if the record doesn't exist in the second sheet. Here's the code I have for this section of my program, I'm a bit confuse as to how to accomplish this and I'm hoping someone will be willing to take a look and give me some suggestions, thanks.
*Explanation:
I'm looking for the unique records in column B and I'll be searching over 3000 cells in that column. If the records exist in sheet 1 but not in sheet 2 they should be deleted.
Option Explicit
Sub RemoveReversionItems()
Dim wbook As Workbook, Wsheet As Worksheet, wbName As String, wsName As String
Dim AlphaRange As Range, ReversionRange As Range
Dim AlphaArray
Dim ReversionArray
Dim x As Long
Dim AlphaSheetColumn As String: AlphaSheetColumn = "B" 'The column with the PO#
Dim ReversionSheetColumn As String: ReversionSheetColumn = "B" 'The column with the PO#
For Each wbook In Workbooks
If wbook.Name <> ActiveWorkbook.Name Then wbName = wbook.Name
Workbooks(wbName).Activate
'********************************
' Look for Reversion Queue
'********************************
For Each Wsheet In wbook.Worksheets
wsName = Wsheet.Name
If Wsheet.Name Like "Revers*" Then
MsgBox "This workbook is named " & wbName & " The Sheet is " & wsName
'Get Reversion Range
With Sheets(wsName)
Set ReversionRange = .Range(.Range(ReversionSheetColumn & "2"), _
.Range(ReversionSheetColumn & rows.Count).End(xlUp))
ReversionArray = ReversionRange
End With
End If
Next Wsheet
'*****************************
' Look for Alpha Queue
'*****************************
For Each Wsheet In wbook.Worksheets
wsName = Wsheet.Name
If Wsheet.Name Like "PO_LN*" Then
'Load Alpha WorkSheet array
With Sheets(wsName)
Set AlphaRange = .Range(.Range(AlphaSheetColumn & "2"), _
.Range(AlphaSheetColumn & rows.Count).End(xlUp))
AlphaArray = AlphaRange
End With
MsgBox "This workbook is named " & wbName & " The Sheet is " & wsName
End If
Next Wsheet
If IsArray(ReversionArray) Then
For x = UBound(ReversionArray) To 1 Step -1
If AlphaArray <> ReversionArray(x, 2) Then
ReversionRange.Cells(x).EntireRow.Interior.Color = 255 'Newtest
End If
Next
Else
End If
Next wbook
End Sub
This function compares 2 data sheets with the same columns based on a primary key. It will highlight non-matched rows in orange and where the rows do match it will find any differences in the field values and highlight red and create a comment to show mismatched value (you can always removed this functionality)
Just pass in the 2 sheet names, the primary key col and whether data has col headers.
eg. strResult=CompareDataSheets("Sheet1","Sheet2",1,True)
Function CompareDataSheets(ByVal sht1 As String, ByVal sht2 As String, ByVal pkCol As Integer, ByVal hasHeaders As Boolean) As String
Dim ws1, ws2 As Worksheet
Dim x As Integer
Dim nmSht1, nmSht2, colDiffs, colName As String
Dim strIdentifier As String
Dim vmatch As Variant
Set ws1 = ActiveWorkbook.Sheets(sht1)
Set ws2 = ActiveWorkbook.Sheets(sht2)
On Error GoTo Err
If hasHeaders Then x = 2 Else x = 1
'Find Non Matches in sheet1
Do Until ws1.Cells(x, pkCol).Value = ""
vmatch = Application.Match(ws1.Cells(x, pkCol).Value, ws2.Columns(pkCol), 0)
If IsError(vmatch) Then
ws1.Rows(x).Interior.Color = 49407
Else
'Find Matched PK Column diffs
iCol = 1
Do Until ws1.Cells(1, iCol).Value = ""
If ws1.Cells(x, iCol).Value <> ws2.Cells(x, iCol).Value Then
If hasHeaders Then
colName = ws1.Cells(1, iCol).Value
Else
colName = iCol
End If
With ws1.Cells(x, iCol)
.Interior.Color = 5263615
.ClearComments
.AddComment sht2 & " Value=" & ws2.Cells(x, iCol).Value
End With
If ws2.Cells(x, iCol).Value <> "" Then
With ws2.Cells(x, iCol)
.Interior.Color = 5263615
.ClearComments
.AddComment sht1 & " Value=" & ws1.Cells(x, iCol).Value
End With
End If
End If
iCol = iCol + 1
Loop
End If
x = x + 1
Loop
If Len(nmSht1) > 0 Then nmSht1 = Left(nmSht1, Len(nmSht1) - 1)
If hasHeaders Then x = 2 Else x = 1
'Find Non Matches in sheet2
Do Until ws2.Cells(x, pkCol).Value = ""
vmatch = Application.Match(ws1.Cells(x, pkCol).Value, ws2.Columns(pkCol), 0)
If IsError(vmatch) Then
ws2.Rows(x).Interior.Color = 49407
End If
x = x + 1
Loop
If Len(nmSht2) > 0 Then nmSht2 = Left(nmSht2, Len(nmSht2) - 1)
CompareDataSheets = "Done!"
Exit Function
Err:
CompareDataSheets = "Error: " & Err.Description
End Function

VBA to keep certain columns and remove all others

As topic says I have a vba code which does the job: remove all columns of sheet "incidents" and keep only the columns with names "Status", "Name" and "Age"
But for some reason, after a few thousand rows, it does not work properly and removes the data/cells of that columns that is keeping , and also works quite slow.
There is any other way to do this? More efective? At least to not remove any cell of that columns which must remain in the sheet.
Thanks in advance (code below).
Sub Cleanup_report2()
Dim currentColumn As Integer
Dim columnHeading As String
For currentColumn = Worksheets("Incidents").UsedRange.Columns.CounT To 1 Step -1
columnHeading = Worksheets("Incidents).UsedRange.Cells(1, currentColumn).Value
'CHECK WHETHER TO KEEP THE COLUMN
Select Case columnHeading
Case "Status", "Name", "Age"
'Do nothing
Case Else
If InStr(1, _
Worksheets("Incidents").UsedRange.Cells(1, currentColumn).Value, _
"DLP", vbBinaryCompare) = 0 Then
Worksheets("Incidents").Columns(currentColumn).Delete
End If
End Select
Next
End Sub
It should be quicker to only do one delete operation:
Sub Cleanup_report2()
Dim currentColumn As Integer
Dim columnHeading As String
Dim rDelete As Excel.Range
With Worksheets("Incidents_data")
For currentColumn = .UsedRange.Columns.Count To 1 Step -1
columnHeading = .UsedRange.Cells(1, currentColumn).Value
'CHECK WHETHER TO KEEP THE COLUMN
Select Case columnHeading
Case "Status", "Name", "Age"
'Do nothing
Case Else
If InStr(1, columnHeading, "DLP", vbBinaryCompare) = 0 Then
If rDelete Is Nothing Then
Set rDelete = .UsedRange.Cells(1, currentColumn)
Else
Set rDelete = Union(rDelete, .UsedRange.Cells(1, currentColumn))
End If
End If
End Select
Next
End With
If Not rDelete Is Nothing Then rDelete.EntireColumn.Delete
End Sub
Here is my anser... hope this helps...
Sub removeColumns()
Dim rng As Range 'store the range you want to delete
Dim c 'total count of columns
Dim i 'an index
Dim j 'another index
Dim headName As String 'The text on the header
Dim Status As String 'This vars is just to get the code cleaner
Dim Name As String
Dim Age As String
Dim sht As Worksheet
Status = "Status"
Name = "Name"
Age = "Age"
Set sht = Sheets("Incidents")
sht.Activate 'all the work in the sheet "Incidents"
c = Range("A1").End(xlToRight).Column
'From A1 to the left at the end, and then store the number
'of the column, that is, the last column
j = 0 'initialize the var
For i = 1 To c 'all the numbers (heres is the columns) from 1 to c
headName = Cells(1, i).Value
If (headName <> Status) And (headName <> Name) And (headName <> Age) Then
'if the header of the column is differente of any of the options
j = j + 1 ' ini the counter
If j = 1 Then 'if is the first then
Set rng = Columns(i)
Else
Set rng = Union(rng, Columns(i))
End If
End If
Next i
rng.Delete 'then brutally erased from leaf
End Sub

Resources