I am trying to force a specific range of cells in Excel to auto capitalize a specific phrase.
For example: We commonly enter type of aircraft such as Saab, Citation, etc. I have a VB script to force Proper Case but there are other times that we abbreviate such as DA20, CJ3, etc.
What I would like (if this is even possible) is for the long names (if used) to remain Proper Case however if they type specific phrases, I would like it to ignore the script and allow it as entered OR auto capital the first two characters.
Diamond or DA20 would be acceptable
Citation or CJ3 would be acceptable
What I don't want is someone that is lazy to type
citation or cj3
diamond or da20
Is this possible? I would be willing to create a whitelist of sorts of all the abbreviations if necessary that would be allowed.
I was hoping some sort "IF" statement may work on the VBA script but I am unsure how to write this.
You can trigger auto-updating of certain ranges using the Worksheet Change event. This requires the user to partially enter the desired input (they need to exit the cell for it to trigger) and will auto-fill the remainder. For instance:
Public boolChanging As Boolean
Private Sub Worksheet_Change(ByVal rng As Range)
Dim strAutoFinish As String, iStartPos As Integer
'Exit unless updates occur when and where you want
If boolChanging Or rng.Row < 1 Or rng.Column <> 1 Or rng.Columns.Count > 1 Or rng.Rows.Count > 1 Then Exit Sub
If rng = "" Then Exit Sub 'This needs to be here in case multiple cells are editted
boolChanging = True
strAutoFinish = ";DA20;Diamond;CJ3;Citation;..."
iStartPos = InStr(UCase(strAutoFinish), ";" & UCase(rng))
If iStartPos > 0 Then
rng = Mid(strAutoFinish, iStartPos + 1, InStr(iStartPos + 1, strAutoFinish, ";") - iStartPos - 1)
Else 'Leave this part if you want it to delete invalid entries
rng = ""
End If
boolChanging = False
End Sub
Related
I have always to delete thirty values from a column, I have managed to "create" a code, that does that, however when one of the values is not found, the code bugs and deletes the entire column.
I'm looking for some piece of code that ckecks if the values exists, if not it just skips it.
I'd rather not use that kinda code that prompts a text box to input the value, since I have to delete 30 of them, which have different names.
While writing this question I tried this so far, however the codes keeps asking for the next object, which requires me to click at lest 29 times
Sub IfContains()
If InStr(ActiveCell.Value, "string1") > 0 Then
ActiveCell.Delete = True
Else
If InStr(ActiveCell.Value, "string2") > 0 Then
ActiveCellDelete = True
End If
End If
End Sub
This might be a better approach. You have only one string to configure, delimited by the tilde (~) character. Then split that into an array of individual values and use a loop to look for every value of the array.
Sub IfContains()
Dim x As Integer
Dim values As Variant
values = "string1~string2~string3" ' using a tilde (~) to separate the values
values = Split(values, "~") ' make an array of individual values
For x = 0 To UBound(values)
If InStr(1, ActiveCell.Value, values(x)) > 0 Then ActiveCell.Delete
Next
End Sub
I'm trying to build a function to return the end string/cell value of an xlFillSeries. Is there any way to do it without actually writing to the worksheet and then selecting last cell? I want to avoid manipulating the worksheet/workbook
.
Here is the code to generate the series:
Dim SeqStart As String, SeqInt As Integer
SeqStart = "XYZ100"
SeqInt = 42 ' Function should return XYZ141
With Range("A1")
.Value = UCase(SeqStart)
If SeqInt > 1 Then
.AutoFill Destination:=Range("A1").Resize(SeqInt), Type:=xlFillSeries ' Will cause error if only 1 sample sequence
End If
End With
I want to utilize XlFillSeries as it handles odd data well, Eg: If my SeqStart = A1B100 then I can't utilize Regex to strip this down to just numbers, perform math, and then put it back together as there is a B in the middle of the string. I do know the series will/should always end in numbers, but I've struggled a bit to strip just the numeric portion from the right hand of the string without knowing string length and or mix of alphanumeric oddities.
So I guess my question could be answered by figuring out how to strip numbers from right side of string and then doing math and putting string back together. The numbers are what increments.
Or, I would just utilize XlFillSeries but without actually writing to the workbook. Currently I did just set it up so that it writes to a "temp sheet" and then captures the last cell and deletes the temp sheet, but I wondered if there was a better way.
Specifically talking about XlFillSeries there is no way to utilize it without writing to a Range which must be "real cells". Therefor the best method is to utilize a "temp sheet" and return the last cell. It may be possible to utilize functions to strip numbers from right hand side of string and then re-build string, but I trust XlFillSeries more and have resigned to just using a "temp sheet".
Here is my function:
Note: There are some custom functions that I wont include, but you can guess what they do based on the name!
Public Function EndOfXlFillSeries(SeqStart As String, SeqInt As Integer) As String
Dim DestSheet As Worksheet
WorksheetCreateDelIfExists ("XLFillSeriesTmp")
Set DestSheet = Worksheets("XLFillSeriesTmp")
With DestSheet.Range("A1")
.Value = UCase(SeqStart)
If SeqInt > 1 Then
.AutoFill Destination:=DestSheet.Range("A1").Resize(SeqInt), Type:=xlFillSeries ' Will cause error if only 1 SeqInt
Else
EndOfXlFillSeries = SeqStart
End If
End With
Dim lRow As Integer
lRow = lRowOfCol(1)
EndOfXlFillSeries = DestSheet.Range("A" & lRow).Value
Call WorksheetDelete(DestSheet)
End Function
I am trying to create a VBA project like this, but I'm having a hard time using the LIKE function and nothing seems to happen when I hit the run button.
What I'm trying to do:
If the first digit is either a number or a blank cell in B4:B245, then enter a text in range D4:245.
If the last digit of the numeric is even in C4:C245, then enter a text in range D4:D245.
More info:
Product codes were imported
LEFT function was used to find the "First digit of product code"
RIGHT function was used to find the "Numeric digits of product code"
My current position in excel and VBA:
Sub number()
Dim first As Range
Set first = Range("B4:B259")
Dim numeric As Range
Set numeric = Range("C4:B259")
Dim DColumn As Range
Set DColumn = Range("D4:D259")
For Each first In DColumn
If first Like " " Then
DColumn = "Invalid Part Number"
DColumn.Interior.ColorIndex = 6
End If
Next
End Sub
The below macro will perform 3 tests & each will get it's own output.
Check for Numeric or blank first character
Check for Even ending character
Check for Odd ending character
These test are not in unison - the output will be one, or none. As soon as a test statement is TRUE, the loop will end for that cell and other values will not be tested.
For example, this macro will not provide you outputs when #1 & #2 from above are true. It will only tell you if #1 is true.
This code does not require you to split the product codes. The macro will work with them as is
Sub MyNum()
Dim xCell As Range, Product_Code As Range
Set Product_Code = Sheets("Sheet1").Range("A2:A9") '<-- Update sheet name
For Each xCell In Product_Code
If IsNumeric(Left(xCell, 1)) Or Left(xCell, 1) = " " Then
xCell.Offset(0, 1) = "Invalid Product: Char 1 = Numeric or Null"
ElseIf Right(xCell, Len(xCell) - 1) Mod 2 = 0 Then
xCell.Offset(0, 1) = "Even Ending Range"
ElseIf Right(xCell, Len(xCell) - 1) Mod 2 <> 0 Then
xCell.Offset(0, 1) = "Odd Ending Range"
End If
Next xCell
End Sub
I am writing a VBA code to go through a specified range or ranges, look for a keyword provided by the user at run-time, and grab the value in the cell offset from the cell with the keyword by an amount also provided by the user. For instance, if you wanted to look through A1:B10 for the word "Apple" and then grab the value in the cell to the right of every instance of "Apple", it can do that. Two weird things have been occurring for me. First and not so weird, when I run it and click the cancel button on the userform that only contains the single line "Unload Me", it throws an error saying it expected and End Sub statement, but it has one. I don't know why it is doing that. Weird thing number 2. Whenever I click and move the cursor to the end of the file after the Cancel_Click() sub, my excel crashes and closes. Every. Single. Time. And it is weird that it does that just from me clicking. It also sometimes happens when I click around the Cancel_Click() sub or hit enter around there too. Just simply from clicking. I don't get it. Any ideas? Code contained in the userform is below. Fyi, the user can input ranges like "A1:A10,E1:E10" separated by commas for multiple ranges. I don't think it is important for this question, but I thought I would add that since i don't know how to add the userform here, if you even can.
Private Sub Accept_Click()
'Searches for string input into the KeywordBox
'Grabs contents of the cell defined by the OffsetBox
'The range it searches through is defined by the RangeBox
Dim rawRange As String: rawRange = Me.RangeBox.Text
Dim rawOffset As String: rawOffset = Me.OffsetBox.Text
Dim Keyword As String: Keyword = Me.KeywordBox.Text
Dim numOfRanges As Integer: numOfRanges = 1
Dim Ranges() As Range
Dim commaLoc As Integer: commaLoc = -1
Dim tempRange As String: tempRange = rawRange
Dim offset As Integer
Dim values() As Double
Dim valCount As Integer: valCount = 0
'--------------------------------------------------------
'Set ranges
For i = 1 To Len(rawRange)
If (Mid(rawRange, i, 1) = ",") Then
numOfRanges = numOfRanges + 1
End If
Next
ReDim Ranges(numOfRanges) As Range
If (Not numOfRanges = 1) Then
For i = 1 To numOfRanges - 1
commaLoc = InStr(1, tempRange, ",")
Set Ranges(i) = Range(Left(tempRange, commaLoc - 1))
tempRange = Right(tempRange, Len(tempRange) - commaLoc)
Next
End If
Set Ranges(numOfRanges) = Range(tempRange)
'---------------------------------------------------------
'Set offset
If (IsNumeric(rawOffset)) Then
offset = CInt(rawOffset)
Else:
MsgBox ("Offset was not input as a number")
Exit Sub
End If
'----------------------------------------------------------
'Searches for keyword
For i = 1 To numOfRanges
For Each cell In Ranges(i)
If (cell.Value = Keyword) Then
valCount = valCount + 1
End If
Next
Next
ReDim values(valCount) As Double
valCount = 0
For i = 1 To numOfRanges
For Each cell In Ranges(i)
If (cell.Value = Keyword) Then
valCount = valCount + 1
values(valCount) = cell.offset(0, offset).Value
End If
Next
Next
For i = 1 To valCount
Range("I" & i).Value = values(i)
Next
Unload Me
End Sub
I've had similar, weird things happen to me. A good thing to try is to force the VBA project to reset, then save, exit, and restart Excel.
To force a project reset, add an Enum to the general section of one of your code modules. It doesn't matter what the enum is...make it something simple, like
Enum stoplight
Red
Yellow
Green
End Enum
As you do that, you'll get a message saying that it will reset your project. That's fine; let that happen. Then save your Excel workbook, exit excel completely, start it up again, reload your workbook, go into the VBA Editor, and delete the enum you added. Then recompile and see if things work better for you.
You put an "Exit Sub" in the set offset, this is probably causing your problem.
I was able to fix the issue by making a new workbook and copying everything over. It worked fine. I think the original was corrupted somehow. For those having the same issue, I think Rich Holton's answer would be worth a try in case you have more than just a few things to copy. Thanks everyone for you time and input on this!
I'm looking for a simple Excel VBA or formula that can convert an entire row in Excel from 'number stored as Text' to an actual Number for vlookup reasons.
Can anyone point me in the right direction?
Better Approach
You should use INDEX(MATCH) instead of VLOOKUP because VLOOKUP behaves in an unpredictable manner which causes errors, such as the one you're presumably experiencing.
INDEX ( <return array> , MATCH ( <lookup value> , <lookup array> , 0) )
Using 0 as the last argument to MATCH means the match must be exact
Here is some more in-depth information on INDEX(MATCH)-ing
Further
Add zero +0 to convert a value to a number.
This can be (dangerously) extended with IFERROR() to turn non-numeric text into a zero:
=A2+0
=IFERROR(A2+0,0)
For the inverse, you can catenate an empty string &"" to force the value to be a string.
Notes
If 0 is not used as the last argument to MATCH, it will find all sorts of unexpected "matches" .. and worse, it may find a different value even when an exact match is present.
It often makes sense to do some extra work to determine if there are duplicates in the MATCH lookup column, otherwise the first value found will be returned (see example).
Help with MATCH comes from here, notably the matching logic the 3rd argument controls.
This should work if you add it before your vlookup or index/match lines:
Sheets("Sheet1").UsedRange.Value = Sheets("Sheet1").UsedRange.Value
I did find this, but does anyone have a formula as well?
Sub macro()
Range("F:F").Select 'specify the range which suits your purpose
With Selection
Selection.NumberFormat = "General"
.Value = .Value
End With
End Sub
http://www.ozgrid.com/forum/showthread.php?t=64027
Try this:
Sub ConvertToNumber()
Application.ScreenUpdating = False
Dim cl As Range
For Each cl In Selection.Cells
cl.Value = CInt(cl.Value)
Next cl
Application.ScreenUpdating = True
End Sub
To use it, simply select the relevant block of cells with the mouse, and then run the macro (Alt+F8 to bring up the dialogue box). It will go through each cell in the selected range and convert whatever value it holds into a number.
I wrote a custom vlookup function that doesn't care about data formats. Put this into a module in VBA and use = VLOOK instead of = VLOOKUP
Public Function VLook(sValue As String, rDest As Range, iColNo As Integer)
' custom vlookup that's insensitive to data formats
Dim iLastRow As Long
Dim wsDest As Worksheet
Set wsDest = Sheets(rDest.Parent.Name)
iLastRow = wsDest.Range(wsDest.Cells(100000, rDest.Column).Address).End(xlUp).Row
If iLastRow < rDest.Row + rDest.Rows.Count Then
For X = rDest.Column To rDest.Column + rDest.Columns.Count
If wsDest.Cells(100000, X).End(xlUp).Row > iLastRow Then iLastRow = wsDest.Cells(100000, X).End(xlUp).Row
Next X
End If
sValue = UCase(Application.Clean(Trim(sValue)))
For X = rDest.Row To iLastRow
If UCase(Application.Clean(Trim(wsDest.Cells(X, rDest.Column)))) = sValue Then
VLookDM = wsDest.Cells(X, rDest.Column + iColNo - 1)
Exit For
End If
Next X
End Function
The easiest way I can think of is using the built-in function =VALUE(TEXT_TO_CONVERT_TO_STRING).