Find a text in a range using EPPlus - vb.net

I'm trying to find a text in an excel sheet (ws), but I cannot be sure where exactly will be that text, I only know it will be in a given range (A1:B64).
When I use this code (for test purpouse), it works fine and I can find the value:
var Row as object = From cell In ws.SelectedRange(2,2)
Where cell.Value.ToString().Equals("any text")
Select cell.Start.Row
But when I changed the code to this:
var Row as object = From cell In ws.SelectedRange("A1:B64")
Where cell.Value.ToString().Equals("any text")
Select cell.Start.Row
I get an error that said:
System.NullReferenceException: 'Object reference not set to an instance of
an object.'
OfficeOpenXml.ExcelRangeBase.Value.get returned Nothing.
I also tried change the values for the selected ranges to:
ws.SelectedRange(ws.Dimension.Address)
ws.SelectedRange(ws.Dimension.Start.Row, ws.Dimension.End.Column)
ws.SelectedRange(1,1,64, 2)
ws.Cells("A1:B64")
All of them throw an error.
Any help?
Thanks in advance.

Couldn't it be that you have cells within the range that has no value set? In that case EPPlus will return null and your ToString() call will throw an exception.
Haven't tried this code myself, but maybe you can use the "Safe Navigation Operator" in C#? Like this:
var Row as object = From cell In ws.SelectedRange("A1:B64")
Where cell.Value?.ToString().Equals("any text")
Select cell.Start.Row

I fixed my problem doing this:
Dim Row as object = From cell In ws.SelectedRange("A1:B64")
Where cell.Value <> Nothing AndAlso cell.Value.ToString().Equals("any text")
Select cell.Start.Row

Related

How to refer to Word Field by name in VBA Code?

I want to update a word field content using VBA. I already have a code that works, but I have to refer to the field's index instead of field's name, which I would prefer.
The code I have is as follows:
Sub UpdateField()
Dim myString As String
myString = "asdf"
ActiveDocument.Fields(1).Result.Text = myString
End Sub
Suppose that the field's name is MyField1. The following code will not work (I get the Run-time error '13': Type mismatch'.
Sub UpdateField()
Dim myString As String
myString = "asdf"
ActiveDocument.Fields("MyField1").Result.Text = myString
End Sub
I create my word fields from File Menu > Informations > Advanced Properties > Custom Tab.
So, how to refer to the field's name when we want to update its content?
These are DocProperty fields. If you press Alt+F9 you'll see the field codes.
A DocProperty field references (links to) a Document Property. The Document Property has the name, but this does not "name" the field. Nor is it possible to update a DocProperty field directly since it links to the Document Property. It might be possible to make it temporarily display something else, but this will be lost any time the field is updated.
In order to update a DocProperty field it's necessary to update the underlying Document Property. For example
Sub EditDocPropUpdateDocPropertyField()
Dim doc As Word.Document
Dim prop As Office.DocumentProperty
Dim propName As String
Dim newPropValue As String
Set doc = ActiveDocument
propName = "MyField"
newPropValue = "new value"
Set prop = doc.CustomDocumentProperties(propName)
prop.value = newPropValue
doc.Fields.Update
End Sub
In the VBE, the Object Browser is a great way to find out what's possible. When I find Word>Field and click on it, I see a list of the members of Field. Name is not in that list. This means that the field object does not have a Name property. That's why you get the error.
You can work around this. One way is to create a bookmark around the field in question. Then in code, find the bookmark by name, then find the field by index inside the bookmark range.
Sample to set text to fields by field name:
ThisDocument.FormFields.Item("MyField1").Result = "hello"

Using the Find VBA function with Defined String

Hey maybe I'm not seeing something obvious here but how can you use the Find VBA function with a predefined variable. I'm using a concatenation of a string assigned from a user form and just "total " in front of it, yet I can't return the row.
Below is my code
Dim HBWS As Worksheet
Dim TickerString As String
TickerString = "Total " & TTB
Set HBWS = Sheets("Hoenheimm Worksheet")
BorrowColumn = HBWS.Cells.Find(What:="Borrow").Column 'Works just fine
TickerRow = HBWS.Cells.Find(What:=TickerString).Row 'Throws an error
Note that TTB is set to a ticker ex. AAPL, and I can check in my local windows that Tickerstring is in fact = to "Total AAPL"
I would expect the .Row column to give me the row on my worksheet as to where this string is located.
EDIT: the error being thrown is as follows...
"Run-Time error '91':
Object Variable or With block variable not set"
Any throughts,
Thanks
You're invoking Range.Find. That method returns a Range object reference - and when it does not find what it's told to look for, it returns Nothing, i.e. a null reference.
TickerRow = HBWS.Cells.Find(What:=TickerString).Row 'Throws an error
What this code is doing (and the working instruction just above it), is assuming that Find returns a valid object reference.
Apparently HBWS.Cells does not contain "Total " & TTB (whatever TTB is), so your code is effectively trying to invoke Range.Row against a Range reference that's Nothing... which is illegal, and raises run-time error 91 as you're experiencing.
You shouldn't assume that Find will return a valid reference, ever. Split it up, and validate the returned object reference with an If ... Is Nothing check:
Set tickerResult = HBWS.Cells.Find(What:=TickerString)
If Not tickerResult Is Nothing Then
tickerRow = tickerResult.Row
Else
'tickerString was not found.
'watch for leading/trailing/extra spaces if the string does *look* legit.
End If
When calling Range.Find, you should always provide a value for the optional parameters, because its implementation "remembers" values from previous invocations, and this is easily bug-prone.

VB.NET DataGridView not Returning Complete Value

I am trying to read the value of a cell that I have just typed into, using the CellValueChanged event of a DataGridView and the following line
Dim InitialString As String = DataGridView1(e.ColumnIndex, e.RowIndex).Value.ToString
The value in the cell is "11048109 20OCT2015 J5572 51" but InitialString has a value of "11048109" and the rest of the string is missing.
I have also used this line...
InitialString = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString
With the same result. Am I using the wrong event?
Thanks in advance.

`Is` operator does not return true for two range variables that point to the same cell

I have a custom class named imera in which I include a range property named date_cell.
When creating a collection of imera's, every imera's date_cell is set to reference to a specific cell in excel.
While attempting to search within the collection by date_cell:
Option Explicit
Public imeraCol as Collection
Sub searchByDateCell()
Dim day As imera
Dim LastMetrisi As Range
Set LastMetrisi = Range("C27")
For Each day In imeraCol
If day.date_cell Is LastMetrisi Then
'Do something
End If
Next day
Set day = Nothing
End Sub
the "Is" operator doesn't seem to work as expected and return true, although I have tested by debug.print that in my colection exists an imera with date_cell set to range("C27").
And as a result the 'Do something section above, never executes.
Is there any explanation why might this happening?
The Is operator will only return true when comparing the same instance of an object. From this MDSN article:
The Is operator determines if two object references refer to the same
object. However, it does not perform value comparisons. If object1 and
object2 both refer to the exact same object instance, result is True;
if they do not, result is False.
You could compare day.date_cell.address instead to check for the same range.
If day.date_cell.Address = LastMetrisi.Address Then
'Do Something...

VBA function result type mismatch

I am trying to run as a macro a custom Excel function XpathOnUrl from the add-in called SeoTools by Niels Bosma. The function runs fine and it seems that I am able to store its result in a variable. This variable can then be correctly output to an Excel cell, but when I try to look for a string in it in the next part of the macro, I get the error Run-time error '13': Type mismatch. From what I understand from here, the function returns an array, but when I try to access it as the first item of the array, I get the same error. I tried to convert the variable into a string with CStr, but no luck there either. What am I missing?
Here's the problematic part of the code:
WebSite = Sheet1.Range("A1")
contactPage = Application.Run("XPathOnUrl", WebSite, "//a[contains(translate(#href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),""contact"")]", "href")
MsgBox TypeName(contactPage) 'trying to find out the data type results in 'Error'
If Left(contactPage(0), 4) = "http" Then
Sheet1.Range("B1").Value = contactPage
ElseIf InStr(contactPage, "/") = 1 Then
Sheet1.Range("B1").Value = WebSite & contactPage
End If
Just to make it clear: the problem starts only with conditional statements. If I assign the value of the variable directly to a cell like this Sheet1.Range("B1").Value = contactPage, it outputs the correct result.
Here's a easy workaround:
Make XpathURL spit its return to a range. Then, use Range.value to assign the return to a contactpage and clear the range using .Clearcontents property. I think Application.Run is not letting XpathURL return get to contactpage.
Edit: Added the comment below:
Sheet1.Range("B1").Value = Application.Run("XPathOnUrl", WebSite, "//a[contains(translate(#href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),""contact"")]", "href")
contactPage = Sheet1.Range("B1").Value
Did you try the Formula and FormulaR1C1 functions? Just my assumptions.
Try and let us know if it helped.
Sheet1.Range("B1").Formula = WebSite & contactPage
or
Sheet1.Range("B1").FormulaR1C1 = WebSite & contactPage
What does the MsgBox TypeName(contactPage) display?