Trying to use boolean logic within Application.WorksheetFunction.MATCH and getting Type Mismatch error - indexing

I have a worksheet function that is working perfectly fine in the worksheet, however, when I try to reproduce it in a macro I am receiving a Runtime Error 13 Type Mismatch. The function in the worksheet is:
=INDEX(TBQA[Question],MATCH(TRUE,INDEX(TBQA[Answer]=TBQA[#Answer],0),0))
The table I am drawing the values from is named "TBQA". The two columns I am trying to refer to in part of the macro are "Question" and "Answer". I have a UserForm ComboBox that I am using as the comparison reference source named "TBABox" and when I click a button, I want to index the value in the "Question" column that matches the answer in the "Answer" column (which is the source for the ComboBox dropdown values).
Private Sub ShowMeQues_Click()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = Sheets("Information")
Set ws2 = Sheets("Resource")
MsgBox Application.WorksheetFunction.Index(ws1.Range("TBQA[Question]"), _
Application.WorksheetFunction.Match("TRUE", _
Application.WorksheetFunction.Index(ws1.Range("TBQA[Answer]") = TBABox.Value, 0), 0))
End Sub
I believe the issue is occurring when I am trying to get a "TRUE" value where the ws1.Range("TBQA[Answer]") = TBABox.Value, but I could be wrong. Please help. I feel like it is a simple fix that I am just overlooking, but I have been searching the internet to find out a resolution to no avail. Any suggestions welcome. THANK YOU!!! :)

I was able to resolve this issue by taking another route! My main goal was to bypass the 255 Character limit set by VBA with the MATCH function. Please see my other post for the resolution that I came up with. Thank you for your help!!!
https://stackoverflow.com/a/72582313/10443879

Related

Excel 2016 VBA: Set Source Data for a Chart to a Named Table

The title is pretty self-explanatory.
I have a named table, Table_Unit_2_Data, which I would like to set as the source data for a chart that will be created using VBA.
During the recording of a macro I selected the entirety of the table, and inserted a chart. This is the code that I got (Build is the name of the Sheet):
Sub Test()
Range("Table_Unit_2_Data[#All]").Select
ActiveSheet.Shapes.AddChart2(240, xlXYScatterSmoothNoMarkers).Select
ActiveChart.SetSourceData Source:= Range("Build!$Y$1:$AD$2")
End Sub
Well, for one thing, as you can see, a specific $A$1 range is passed into the SetSoureData. This will not work because the range of Table_Unit_2_Data will change.
I attempted this:
With Sheet2.Shapes.AddChart2(240, xlXYScatterSmoothNoMarkers)
.Chart.SetSourceData (Sheet2.Range("Table_Unit_2_Data[#All]"))
End With
But then I get the error "Object Required".
I can't seem to phrase my search queries in such a way as to find relevant answers to this specific question on the internet so I apologize for asking what is likely a redundant question. If someone could help me with this problem I would be greatly appreciative and if anyone has a good article or source online for information regarding the nuances of chart creation within VBA that would also be very helpful.
Thank you.
In addition to what Domenic said (which is correct + would cause the "Object Required" error), your code doesn't make it clear what "Sheet2" is, except that it's the codename of some sheet. From the recorded macro, I can infer that the actual table is on a sheet called "Build", so another possibility to consider is that Sheet2 isn't actually the codename of Sheets("Build"). Again, I can't actually tell from the code provided.
While I do like using sheet codenames, I'd strongly recommend against using them if you're not going to make the names descriptive.
FWIW, there's another way to reference table ranges that's a little more flexible, especially if you're going to be referring to the table elsewhere in the code. Just make a ListObject variable:
Dim UnitTable2 As ListObject
Set UnitTable2 = Sheets("Build").ListObjects("Table_Unit_2_Data")
And you'll be able to reference any part of the table really easily:
Dim rng As Range
'Reference the whole table, including headers:
Set rng = UnitTable2.Range
'Reference just the table data (no headers):
Set rng = UnitTable2.DataBodyRange
'Reference just the data in a single column:
Set rng = UnitTable2.ListColumns("Col1").DataBodyRange
'Reference the headers only
Set rng = UnitTable2.HeaderRowRange

why does this line produce a runtime error?

Working with a code to grab specific data from files and this line:
With sht.Range(Cells(1, 1), Range("A1").SpecialCells(xlCellTypeLastCell))
produces: method 'Range' of object '_worksheet' failed.
I have sht dim'd as worksheet and am just trying to select the range as the whole sheet?
You wrote you "dim'd" sht as worksheet. I assume you are talking about
Dim sht As Worksheet
If you did not do the following, there might be the problem:
set sht = ThisWorkbook.Worksheets("insertnamehere") [the ThisWorkbook. part asumes the worksheet is at the same workbook as the code]
If that does not solve your Problem, pls make a debugoutput (I prefere MsgBox, but only personal preference) of the second part, like MsgBox sht.Range("A1").SpecialCells(xlCellTypeLastCell).Address and post the result here (An address? A new error? If so, wich?)
Hope it helps at least one step forward.
PS: If you set sht allready (not only dim'd it <- love that phrase :P ) pls also edit your post and add the code for that (and anything that might relate)

Spell check an Excel sheet in VBA

I have scoured the Internet and I have found a handful of possible solutions to this issue, but I wanted to ask here as well.
The goal is to click a button, and spell check an entire sheet.
Here's some code
Sub spellCheck()
Sheet1.Cells.CheckSpelling
End Sub
Also, I found this:
Sub SpellCheck()
Dim Checkword As String, Result As Boolean
Checkword = Selection.Value
Result = Application.CheckSpelling(Checkword)
Selection.Offset(0, 1) = Result
End Sub
Any ideas? Neither is working for me. Thanks!
You can check the whole workbook by doing something like:
Sub SpellCheck()
For Each sh In Worksheets
Sheets(sh.Name).Cells.CheckSpelling
Next
End Sub
this will cycle through each sheet in the entire book and run a spellcheck on each one. What I can't figure out yet is how to make the spell checker actually move to the position of the spelling error. So, with the above you just get a list of spelling errors with no context with which to asses them.
I noticed I just had a typo in my code.
Below works:
Sub spellCheck()
Sheet1.Cells.CheckSpelling
End Sub
But, if anyone knows how to do the entire workbook, I'd be interested in that. Thanks.
This code will work on selected cells .This will highlight if any spell mistakes in a cell
Dim Myrange As Range
Selection.SpecialCells(xlVisible).Select
For Each Myrange In Selection
If Application.CheckSpelling(word:=Myrange.Value) = False Then
Myrange.Font.Color = vbRed
End If
Next
OK, so you can use the following command to invoke the toolbar's spellchecker which does move you to the position of the spelling error as long as you have screen updating enabled at the time.
Application.CommandBars("Tools").Controls("Spelling...").Execute
You can use this command embedded in the loop above to loop through the sheets in the workbook and invoke this command on each new sheet.
Cap
This uses a code snippet from a previous answer to restrict the area used for spellchecking to a specific region. Something I needed to do in a small project. This give the full functionallity of the spellchecker with errors shown in context. The rowNumber is calculated elsewhere.The selection range can be fully controlled elsewhere in your code to suit your particular need. Thought this might help others searching this posting.
With Sheets("Sheet1")
slic = CStr(rowNumber)
.Range("AL3:AN" & slic).Select
Application.CommandBars("Tools").Controls("Spelling...").Execute
End With
Thanks to previous posters this solved a problem form me. I am most grateful.

Referring to Dynamic Named Ranges in VBA

I'm having troubling referring to a Dynamic Name Range in VBA.
My ranges are defined as
=OFFSET(Sheet!$B$2,0,0,COUNTA(Sheet!$B:$B)-1,1)
My code should search one range for all entries in another range, the intention being that any missing entries will be added. So far I have
Sub UpdateSummary()
Dim Cell As Range
Dim rngF As Range
Set rngF = Nothing
' Step through each cell in data range
For Each Cell In Worksheets("Aspect").Range("A_Date")
' search Summary range for current cell value
Set rngF = Worksheets("Summary").Range("Sum_Date").Find(Cell.Value) // Does not work
If rngF Is Nothing Then
' Add date to Summary
End If
Set rngF = Nothing
Next Cell
End Sub
The For loop seems to work ok. However, using the .Find method is giving me an error message.
Application-defined or object-defined error
It does work if I replace the named range with a specific range ($B$2:$B$5000), so it seems to be down to how the named range is being passed.
Any ideas would be appreciated.
Thanks.
The error is almost definitely because Excel can't find a named range Sum_Date that refers to a range on a worksheet named Summary. The most common causes are
Sum_Date refers to a sheet other than Summary. Check the RefersTo property of Sum_Date and make sure nothing is misspelled.
There is not a named range Sum_Date, that is, it's misspelled in the VBA code. Check the spelling of the named range in the Name Manager.
There is an error in the RefersTo formula of Sum_Date. It sounds like you already verified that this isn't the case.
I've had the a similar if not the same problem & here's how I solved it:
I first realized that the method I used to create my named range, using the Name Manager, my named range had a scope of Workbook. This is important because, it doesn't belong to the worksheet, & therefore will not be found there.
So, Worksheets("Summary").Range("Sum_Date") would not work for me.
Since my range belonged to the workbook, the way I was able to find is to use ActiveWorkbook.Names("Sum_Date")
For me I used it to remove the formula from named range that I am using in many places. The huge advantage is that named range is updated only once instead of the formula being called for every cell location that ranged is called. Huge time delay difference!
Public last_Selection As String
Private Sub Worksheet_Change(ByVal Target As Range)
'excel data change detection
If Range(last_Selection).Column = 2 Then
'Disable events, so this only executes once
Application.EnableEvents = False
'This can be done with a complex formula in a cell,
'but this is easily understood
Range("B1").End(xlDown).Select
ActiveWorkbook.Names("last_Entry").Value = ActiveCell.Row
'Re-enable so this routine will execute on the next change
Application.EnableEvents = True
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'constantly store the last cell to know which one was previously edited
last_Selection = Target.Address
End Sub
I know this is a very old thread, but I had the same issue today and I was looking for solution for quite a long time. So maybe this will help someone.
The named "range" defined by the =OFFSET(...) formula is actually a named FORMULA, so in VBA you have to evaluate it first to get the range. E.g.:
Set rgNamedRange = Worksheets("Summary").Evaluate("Sum_Date")
Credits to a guy named "shg" from mrexcel.com, who got me on right track. :)
I have been experimenting with this for a few days and eventually I came up with the following. It may not be the most efficient but it did work for me!
The named range of "OhDear" was set up in the normal way
Dim vItem As Variant
Set vItem = Names("OhDear")
Debug.Print vItem.Name
Worth a try don't you think!
This does not work if instead of using a variant you use something like: Dim Nm as Name: Set Nm = Names("OhDear"). Any variations using 'Nm' failed!!!

Subscript out of range Error after renaming sheets

I have done a small project, which consists of 5 excel sheet in, code is working fine and I am getting exact result also, but if I rename sheets from sheet1 to some other name I am getting Subscript out of range Error.
What is the reason for this and what needs to be done to overcome this. Please help.
Below is the code
Public Sub amount_final()
Dim Row1Crnt As Long
Dim Row2Crnt As Long
With Sheets("sheet4")
Row1Last = .Cells(Rows.Count, "B").End(xlUp).Row
End With
Row1Crnt = 2
With Sheets("sheet3")
Row2Last = .Cells(Rows.Count, "B").End(xlUp).Row
End With
There is nothing wrong with the code per se. You will get Subscript out of range error if Excel is not able to find a particular sheet which is quite obvious since you renamed it. For example, if you rename your sheet "Sheet3" to "SheetXYZ" then Excel will not be able to find it.
The only way to avoid these kind of errors is to use CODENAME of the sheets. See Snapshot
Here we have a sheet which has a name "Sample Name before Renaming"
So consider this code
Sheets("Sample Name before Renaming").Range("A1").Value = "Blah Blah"
The same code can be written as
Sheet2.Range("A1").Value = "Blah Blah"
Now no matter how many times you rename the sheet, the above code will always work :)
HTH
Sid
The basic issue is that you are referring to sheets using their common names and not their codenames. Whenever you refer to Sheets("sheet4"), you are relying on the sheet having that name in Excel. Codenames are the names assigned in Visual Basic so the end user does not interact with them/as a developer you can change the Excel names any time you like
Using code names is covered at around 9:40 in this Excel help video. You'll note they are quicker to type than the Excel names as do not require the 'Sheets()' qualifier
I couldn't see Sheets("Sheet1") in your code sample but you can switch to codenames for all sheets very quickly by finding/replacing all examples of e.g. 'Sheets("Sheet2").' with 'Sheet2.'
Refer to each sheet by their code names instead. They are set to Sheet1, Sheet2 etc as default, but you can rename them in the Properties window for each sheet if you want. This way you can write your code like below instead, regardless of what you name the sheets.
With Sheet1
Row1Last = .Cells(Rows.Count, "B").End(xlUp).Row
End With
Row1Crnt = 2
With Sheet2
Row2Last = .Cells(Rows.Count, "B").End(xlUp).Row
End With
etc...
I wanted to share my experience battling this problem. Here is the mistake I committed:
Dim DailyWSNameNew As String
lastrow = Sheets("DailyWSNameNew").Range("A65536").End(xlUp).Row + 1 -- This is wrong as I included a placeholder worksheet name in quotes
Correction:
lastrow = Sheets(DailyWSNameNew).Range("A65536").End(xlUp).Row + 1
This solved it.
I encountered this error earlier today but could not use any solution above, I did however eventually managed to solve it myself.
My situation was that I had a list contained in column A. For each cell with a value I stored the value in a variable, created a new sheet and named the sheet according to the value stored in the variable.
A bit later in the code I tried to select the newly created sheet by using the code:
Sheets(ValueVariable).Select
I encountered the "Subscript out of range" error and I couldn't figure out why. I've used similar code before with success.
I did however solve it by casting the variable as a string. Declaring the variable as a string did not seem to work for me.
So, if anyone else encounter this error and want something to try, perhaps this will work for you:
Sheets(Cstr(ValueVariable)).Select