Show "Number stored as Text" error - vba

I'm using an Advanced Filter, among others, with 0 and 1's. The filter works correctly only if in the Data sheet the cells with 1 and 0 have the error message "Number stored as text" displayed. For that I have to manually open the cell with double click and press Enter. Then the error message appears and the filter works. If I don't do that, the filter doesn't work.
Alternatively I can click on the cell with 1 or 0 and press F2 to display the error message.
Is there a way with VBA that I can automatically do that?
Many thanks for your help!

You'll find that buried deep in the Range properties for the cells, specifically in the Errors collection. Just find the cells where that error is present, then set the Ignore property to True:
Public Sub IgnoreNumsAsText()
Dim current As Range
For Each current In ActiveSheet.UsedRange.Cells
With current
If .Errors.Item(xlNumberAsText).Value = True Then
.Errors.Item(xlNumberAsText).Ignore = True
End If
End With
Next current
End Sub

Related

VBA- Using inputbox to filter and copy data

i am working on a userform where i puted a button that when i click on it i got an input box where i try to filter data of the column (E) then after filtering this data copy from colum A1 till the value filtered in the column E in another sheet caaled filtred_data i am using this code this code but it show me a bug dont nw how to fix it
Private Sub CommandButton9_Click()
Dim xno As Integer, Found As Range
Do
xno = Application.InputBox("Enter the number of Top communities ", Type:=1)
If TypeName(xno) = "Boolean" Then Exit Sub
Set Found = Columns("E").Find(what:=xno, lookat:=xlWhole, LookIn:=xlValues)
If Found Is Nothing Then
MsgBox "the number was not found, please try again !!", vbInformation
Else
Found.Range("A1:F10000").Copy Destination:=Sheets("filtred_data").Range("A1:F10000")
End If
Loop
End Sub
if anyone can help me please , thank you
The problem in your case is that you are setting the Found variable to be a single cell by using the Find method. Later in your code, you are trying to copy the A1:F10000 of that ONE cell when you write Found.Range("A1:F1000").
Essentially, your code looks like this (assume Found refers to cell E25):
Range("E25").Range("A1:F1000").Copy
Can you see why that would cause an error?
I'd try to offer more help, but it's hard to determine exactly what you want. Can you possibly give more details about your spreadsheet layouts and an example of what you want to happen?

Changing the Name of an Excel ActiveX ListBox

I have a set of ActiveX controls and subs that fit together like this:
User types into an ActiveX TextBox,
TextBox_Click triggers execution of 3 subs.
The first sub updates the value of a named range on a sheet; based on that updated value a table is created in excel using an offset function
The second sub copies the table range updated in 3 and paste.values into a range on the sheet (to eliminate formulas)
Here's where it is breaking down.
When I set the sheet up I create one ListBox (ListBox1). The third of the three subs mentioned in #2 above tests to see if ActiveX 'ListBox1' exists in the sheet. If not, the intention is the code will determine what the ListBox is called (LB1 or LB2 or LB2 etc), changes the name to 'ListBox1', and pastes the table from #4 above into ListBox1. Then a ListBox1_Click command could trigger a unique set of code to execute.
Right now I'm just testing switching between the names ListBox1 and ListBox2.
The idea is that as a user types into TextBox1 for example, ListBox1 updates at every keystroke. So type "g" and the list shows 20 names starting with the first "g" in the database sheet. Then type "ge" and the list shows 20 names starting with the first "ge" in the database sheet etc etc. The user clicks on a name and ListBox1_click does something unique. If the user was typing in TextBox2 they would see different data in the ListBox (which I would like to rename as ListBox2) and if they click a unique set of code is executed by ListBox2_Click.
The problem in #5 is the I get error 'Object doesn't support this property or method' the FIRST time I try to execute. The second time it is ok. If I do something else on the sheet and come back to it i get the error again.
Here is the code for #5 which is in a Module:
Sub PutListInListBox()
Dim OBJ As Object
On Error Resume Next
Set OBJ = ActiveSheet.OLEObjects("ListBox1")
On Error GoTo 0
If OBJ Is Nothing Then
ActiveSheet.ListBox2.Name = "ListBox1"
End If
ActiveSheet.ListBox1.Clear
ActiveSheet.ListBox1.List = Sheets("Search Criteria Control").Range("G1:G21").Value
End Sub
I have no idea what I'm doing wrong and any help is appreciated.
I hope I'm making this clear.
UPATED CODE
I have a bunch of ActiveX Lables and Text boxes so I used the first form you suggested to search for specific name Cases. I've been reading about it and can't see what I have wrong here. After typing in TB5, the LB doesn't update. I click back to Design Mode and can see that the name is still ListBox2.
Any ideas?
Private Sub TextBox5_Change()
Call UpdateValues(TextBox5.Value)
Call CopyTable
Dim OLEOBJ As OLEObject
For Each OLEOBJ In ActiveSheet.OLEObjects
Select Case OLEOBJ.Name
Case "ListBox1", "ListBox2", "ListBox3"
OLEOBJ.Name = "ListBox1"
OLEOBJ.ListFillRange = Sheets("Search Criteria Control").Range("G1:G21").Address(external:=True)
End Select
Exit For
Next
End Sub
I'll concentrate on your Code#5.
First, if you are changing the name of the ListBox Object, it is better to iterate the Object Collection it belongs to since you are not sure of it's name. Something like this:
Dim oleobj As OLEObject
Dim sh As Worksheet: Set sh = ActiveSheet
For Each oleobj In sh.OLEObjects
Select Case oleobj.Name
Case "LB1", "LB2", "ListBox1", "ListBox2" 'put the possible names here
oleobj.Name = "ListBox1" 'change it to the name you want
End Select
Exit For 'if you have more than 1 ListBox
Next
If you just want to change the name of an existing ListBox, then skip the checking.
For Each oleobj In sh.OLEObjects
oleobj.Name = "ListBox1"
Exit For 'if you have more than 1 ListBox
Next
Now, to assign values or list to it, you can directly assign the source Range, using ListFillRange Property after you've change its name.
oleobj.ListFillRange = Sheets("Search Criteria Control") _
.Range("G1:G21").Address(, , , True) 'add this line within the loop
Take note that you need not clear the previous list. It will automatically update. Since I'm not sure what you want to achieve entirely, I'll stop here. HTH though.

Check if cell was empty Excel VBA

I am writing an Excel Macro to display a warning if the user edits a cell that was previously empty. Basically if a cell is edited, is in column 1, and already contains text I want to display a warning But if it does not have text already, I do not want to.
So what I have tried is the following
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 1 And Not IsEmpty(Cells(Target.Row,Target.Column)) Then
Application.EnableEvents = False
MsgBox "Some Message"
Application.EnableEvents = True
End If
End Sub
The issue I am having is when I am getting the cell to see if it was empty or not, it will never return that it was because, well the user just added stuff to it.
So I want to know if there is a simple way to check the previous state of that cell. I want to find out if the cell WAS empty. Is this possible?
You could use the Worksheet_SelectionChange event to capture the value of the cell that the user has selected in a variable, which happens before they make any changes.
Then when Worksheet_Change is fired, you can refer to that variable.

VBA application.match error 2015

In my Main procedure I want to write a quick if-statement which checks whether the user has made a valid input (user chooses number of project from list of data, see attached screenshot). For that I am checking whether the project number is not part of the list of projects. If that is true, an error message is displayed; if not then a number of other procedures are called.
For some reason though I get error 2015 when I run it, which means that the if-statement is always true, even on correct user entries. Can someone help me understand the error please?
The project number input is a named cell called "IdSelect" and is on a sheet called "Invoice"
The data against which this input is checked is on a sheet called "Input"
The data is stored in column B and called "ProjectList"
Code below (note: I have tried pasting it 5 times but the formatting still won't work this time for some reason - any idea what that could be? The code is properly formatted. Sorry for the messy display; if anyone can tell me what that problem might I would be very grateful!)
Sub Main()
'Turn off screen updating
Application.ScreenUpdating = False
'Define variable for currently active cell to reactivate it afterwards
Dim OldActiveSheet As Object
Dim OldActiveCell As Object
Dim i As Integer
Dim ProjectList As Range
Set OldActiveSheet = ActiveSheet
Set OldActiveCell = ActiveCell
'If-statement to check whether project number is valid or not
Worksheets("Invoice").Activate
'Print to Immediate Window to check value - remove later
Debug.Print Range("IdSelect").Value
If IsError(Application.Match(Range("IdSelect").Value, "ProjectList", 0)) Then
'Print to Immediate Window to check value - remove later
Debug.Print Application.Match(Range("IdSelect").Value, Worksheets("Input").Range("ProjectList"), 0)
MsgBox "Invalid Choice: Project with this number does not exist!"
Exit Sub
Else
'Call procedures to execute
Call SortData
Call Count_Line_Items
Call Count_Total_Rows
Call Write_Services(ServCnt)
Call Write_Expenses(ExpCnt)
End If
'Reactivate previous active cell
OldActiveSheet.Activate
OldActiveCell.Activate
End Sub
Screenshot from "Input" sheet:
The way you refer to range is rather odd.. because you missed out range reference. Oddly enoughbthat you do it correct on the next line at
Debug.Print Application.Match(Range("IdSelect").Value, Worksheets("Input").Range("ProjectList"), 0)
So try this please: (it take me 100 years to format my own post on mobile.....). Make sure to use explicit reference as shown in my sample code below. Set your sheets accordingly.
Dim ws as Worksheet
Set ws = Sheets(1)
IsError(Application.Match(ws.Range("IdSelect").Value, ws.Range("ProjectList"), 0)) Then
And here is for you to read on for error handling on on match.

OnClick in Excel VBA

Is there a way to catch a click on a cell in VBA with Excel? I am not referring to the Worksheet_SelectionChange event, as that will not trigger multiple times if the cell is clicked multiple times. BeforeDoubleClick does not solve my problem either, as I do not want to require the user to double click that frequently.
My current solution does work with the SelectionChange event, but it appears to require the use of global variables and other suboptimal coding practices. It also seems prone to error.
Clearly, there is no perfect answer. However, if you want to allow the user to
select certain cells
allow them to change those cells,
and
trap each click,even repeated clicks
on the same cell,
then the easiest way seems to be to move the focus off the selected cell, so that clicking it will trigger a Select event.
One option is to move the focus as I suggested above, but this prevents cell editing. Another option is to extend the selection by one cell (left/right/up/down),because this permits editing of the original cell, but will trigger a Select event if that cell is clicked again on its own.
If you only wanted to trap selection of a single column of cells, you could insert a hidden column to the right, extend the selection to include the hidden cell to the right when the user clicked,and this gives you an editable cell which can be trapped every time it is clicked. The code is as follows
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'prevent Select event triggering again when we extend the selection below
Application.EnableEvents = False
Target.Resize(1, 2).Select
Application.EnableEvents = True
End Sub
In order to trap repeated clicks on the same cell, you need to move the focus to a different cell, so that each time you click, you are in fact moving the selection.
The code below will select the top left cell visible on the screen, when you click on any cell. Obviously, it has the flaw that it won't trap a click on the top left cell, but that can be managed (eg by selecting the top right cell if the activecell is the top left).
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'put your code here to process the selection, then..
ActiveWindow.VisibleRange.Cells(1, 1).Select
End Sub
SelectionChange is the event built into the Excel Object model for this. It should do exactly as you want, firing any time the user clicks anywhere...
I'm not sure that I understand your objections to global variables here, you would only need 1 if you use the Application.SelectionChange event. However, you wouldn't need any if you utilize the Workbook class code behind (to trap the Workbook.SelectionChange event) or the Worksheet class code behind (to trap the Worksheet.SelectionChange) event. (Unless your issue is the "global variable reset" problem in VBA, for which there is only one solution: error handling everywhere. Do not allow any unhandled errors, instead log them and/or "soft-report" an error as a message box to the user.)
You might also need to trap the Worksheet.Activate() and Worksheet.Deactivate() events (or the equivalent in the Workbook class) and/or the Workbook.Activate and Workbook.Deactivate() events so that you know when the user has switched worksheets and/or workbooks. The Window activate and deactivate events should make this approach complete. They could all call the same exact procedure, however, they all denote the same thing: the user changed the "focus", if you will.
If you don't like VBA, btw, you can do the same using VB.NET or C#.
[Edit: Dbb makes a very good point about the SelectionChange event not picking up a click when the user clicks within the currently selected cell. If you need to pick that up, then you would need to use subclassing.]
I don't think so. But you can create a shape object ( or wordart or something similiar ) hook Click event and place the object to position of the specified cell.
This has worked for me.....
Private Sub Worksheet_Change(ByVal Target As Range)
If Mid(Target.Address, 3, 1) = "$" And Mid(Target.Address, 2, 1) < "E" Then
' The logic in the if condition will filter for a specific cell or block of cells
Application.ScreenUpdating = False
'MsgBox "You just changed " & Target.Address
'all conditions are true .... DO THE FUNCTION NEEDED
Application.ScreenUpdating = True
End If
' if clicked cell is not in the range then do nothing (if condttion is not run)
End Sub
NOTE: this function in actual use recalculated a pivot table if a user added a item in a data range of A4 to D500. The there were protected and unprotected sections in the sheet so the actual check for the click is if the column is less that "E" The logic can get as complex as you want to include or exclude any number of areas
block1 = row > 3 and row < 5 and column column >"b" and < "d"
block2 = row > 7 and row < 12 and column column >"b" and < "d"
block3 = row > 10 and row < 15 and column column >"e" and < "g"
If block1 or block2 or block 3 then
do function .....
end if
I had a similar issue, and I fixed by running the macro "onTime", and by using some global variables to only run once the user has stopped clicking.
Public macroIsOnQueue As Boolean
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
macroIsOnQueue = False
Application.OnTime (Now() + TimeValue("00:00:02")), "addBordersOnRow"
macroIsOnQueue = True
End sub
Sub addBordersOnRow()
If macroIsOnQueue Then
macroIsOnQueue = False
' add code here
End if
End sub
This way, whenever the user changes selection within 2 seconds, the macroIsOnQueue variable is set to false, but the last time selection is changed, macroIsOnQueue is set to true, and the macro will run.
Hope this helps,
Have fun with VBA !!
Just a follow-up to dbb's accepted answer: Rather than adding the immediate cell on the right to the selection, why not select a cell way off the working range (i.e. a dummy cell that you know the user will never need). In the following code cell ZZ1 is the dummy cell
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.EnableEvents = False
Union(Target, Me.Range("ZZ1")).Select
Application.EnableEvents = True
' Respond to click/selection-change here
End Sub