Set a value from a collection to a variable - excel

I am trying to do some debugging and I have a collection I created from several different strings. What I would like to do is go back and set another variable equal to the second item in the collection. Is this possible? See a very simplified example below:
Dim TagForms As New Collection
Dim TagForm1 As String
Dim TagForm2 As String
Dim TagForm3 As String
Dim Test As String
TagForm1 = "Cat"
TagForm2 = "Dog"
TagForm3 = "Pig"
Set TagForms = New Collection
TagForms.Add TagForm1
TagForms.Add TagForm2
TagForms.Add TagForm3
Test = TagForms(2) 'This doesn't work
Set Test = TagForms(2) 'This also doesn't work

As the variable 'Test' is a string, the last code line 'Set Test = TagForms(2)' does not work.
The correct code line is 'Test = TagForms(2)'. This code returns 'Dog'

Related

BAPI_MATERIAL_MRP_LIST returns empty values in VBA

I use an Excel macro to get values from SAP, especially for planned orders.
Function GetOrders(ByVal ProductNumber As String)
Dim OrderList As Object: Set OrderList = SAP.Add("BAPI_MATERIAL_MRP_LIST")
Dim OrderMat As Object: Set OrderMat = OrderList.Exports("MATERIAL")
Dim OrderPlant As Object: Set OrderPlant = OrderList.Exports("PLANT")
Dim OrderTable As Object: Set OrderTable = OrderList.Tables("MRP_IND_LINES")
OrderTable.FreeTable
OrderMat = ProductNumber
OrderPlant = "XXX"
OrderList.Call
Set GetOrders = OrderTable
Set OrderMat = Nothing
Set OrderPlant = Nothing
Set OrderTable = Nothing
End Function
I changed the OrderPlant for the question.
It's working on one PC but using the same SAP account on another one we get some empty values. Specifically all the numbers > 10k are not shown.
On my PC I get something like this as a result from the MRP_IND_LINES table:
P.cons 00XXXXXXXX/XXXXXX/XXXX -21.600.000
P.cons 00XXXXXXXX/XXXXXX/XXXX -3.600.000
On another PC I the -21.600.000 is empty so it shows like this:
P.cons 00XXXXXXXX/XXXXXX/XXXX
P.cons 00XXXXXXXX/XXXXXX/XXXX -3.600.000
The disappearing field is the "REC_REQD_QTY", number 16 of the table BAPI_MRP_IND_LINES (MRP: Single Lines of MRP Elements), Data Type: "QUAN"
The only difference between the PCs is the SAP logon GUI version, 720 on mine and 750 on the other PC.
This happens only on the big numbers. The other fields in the row are downloaded correctly.
I'm not using SAP GUI scripting, but I've created the SAP Object with the row
Set SAP = CreateObject("SAP.Functions.Unicode")

How to compare a FieldGetText with a number?

I have a field that it stores a currency data with the name pdcPrimasVAFVigor.
I can get the value with the FieldGetText method about NotesUIDocument like this:
strPrimasVaf = uidoc.Fieldgettext("pdcPrimasVAFVigor")
And then I check the value and the type:
Msgbox "strPrimasVaf: " + Typename(strPrimasVaf)
This messagebox retrievme:
strPrimasVaf: 122.00 € STRING
If I want to compare strPrimasVaf with any number but the comparision doens't work, then I have tried to convert the data but I always get the next error:
Type Mismatch in method CoerStrToNum...
But, what have I tried?
I have tried to convert the string value before to compare like this:
Dim intPrimasVaf As Integer
intPrimasVaf = CInt(strPrimasVaf) ' Error
Dim dblPrimasVaf As Double
dblPrimasVaf = CInt(strPrimasVaf) ' Error
Dim curPrimasVaf As Currency
curPrimasVaf = CInt(strPrimasVaf) ' Error
Include I have try to change the format like this:
Dim x As Variant
x = Format(strPrimasVaf, "General Number")
Any advice or solution within using FieldGetText?
My advice: work with the backend document object.
Add
Dim doc as Notesdocument
Dim dblPrimasVaf As Double
Set doc=uidoc.document
dblPrimasVaf=doc.pdcPrimasVAFVigor(0)
No conversion needed.
Remove the € from the string with something like:
strPrimasVaf = uidoc.Fieldgettext("pdcPrimasVAFVigor")
strPrimasVaf=cdbl(fulltrim(join(split(strPrimasVaf,"€"),"")))

Searching for a word and not a string?

I want to check a file for a particular word the way I have found posted on various forums is to use the following code...
Dim content = My.Computer.FileSystem.ReadAllText(filePath)
If content.Contains("stringToSearch") Then
'Do your stuff
End If
Which is okay until you discover that it will search and match compound words and the likes. For instance If I search for the string light in a file and it's not there but instead the word lightning is, it will still register as having found a match... Is there a way to find and exact word using VB.net?
As mentioned by Andrew Morton, Regex makes this kind of thing very easy. For instance, if you made a function like this:
Public Function ContainsWord(input As String, word As String) As Boolean
Return Regex.IsMatch(input, $"\b{word}\b")
End Function
You could use it like this:
Dim content = My.Computer.FileSystem.ReadAllText(filePath)
If ContainsWord(content, "stringToSearch") Then
'Do your stuff
End If
If you wanted to, you could even make it an extension method on the String type, by putting it in a Module and adding the ExtensionAttribute, like this:
<Extension>
Private Function ContainsWord(input As String, word As String) As Boolean
Return Regex.IsMatch(input, $"\b{word}\b")
End Function
And then you could call it like this:
Dim content = My.Computer.FileSystem.ReadAllText(filePath)
If content.ContainsWord("stringToSearch") Then
'Do your stuff
End If
Another method, using Regex.Matches, which allows to search for a collection of words and returns a Dictionary(Of String, Integer()).
The Dictionary Key represent the matched word, the Value, as an Array of Integers, all the positions inside the File where the word was found.
The extension method requires 2 parameters:
- the path of the file to search
- a boolean value, used to specify whether the search should be case sensitive.
Proposed as an extension method of IEnumerable(Of String):
Dim fileName As String = "[File Path]"
Dim searchWords As String() = {"light", "lighting", "clip", "clipper", "somethingelse"}
Dim result = searchWords.FindWords(fileName, False)
Print a result of the matches found:
result.ToList().ForEach(
Sub(w)
Console.WriteLine($"Word: {w.Key} Positions: {String.Join(", ", w.Value)}")
End Sub)
Extension method:
Imports System.IO
Imports System.Runtime.CompilerServices
Imports System.Text
Imports System.Text.RegularExpressions
Module modIEnumerableExtensions
<Extension()>
Public Function FindWords(words As IEnumerable(Of String),
fileName As String,
caseSentive As Boolean) As Dictionary(Of String, Integer())
Dim pattern As StringBuilder = New StringBuilder()
pattern.Append(String.Concat(words.Select(Function(w) $"\b{w}\b|")))
Dim options As RegexOptions = RegexOptions.Compiled Or
If(caseSentive, RegexOptions.Multiline, RegexOptions.IgnoreCase Or RegexOptions.Multiline)
Dim regx As New Regex(pattern.ToString().TrimEnd("|"c), options)
Dim matches As MatchCollection = regx.Matches(File.ReadAllText(fileName))
Dim groups = matches.OfType(Of Match).
GroupBy(Function(g) g.Value).
ToDictionary(Function(g) g.Key, Function(g) g.Select(Function(m) m.Index).ToArray())
Return groups
End Function
End Module
The shortest and fastest way to do this is using ReadLines with LINQ queries, specialy when you are working with a large files.
Dim myword As String = "Book"
Dim reg = New Regex("\b" & myword & "\b", RegexOptions.IgnoreCase)
Dim res = From line In File.ReadLines(largeFileName)
Where reg.IsMatch(line)
If your file containts "Book", "Books", "Book." and "Book," the results will be:
Book
Book,
Book.
And you can working with results as following
TextBox1.Text = resLines.Count
Or
TextBox1.Text = resLines(0)
Edited to make it consering "." and "," etc.

Exporting Locations for a Customer using Acumatica API

I'm trying to use the Acumatica Web Services API to export all Locations for a Customer. I would expect that using the Locations screen I could set a filter on the Customer ID field, which I think is LocationSummary.Customer, and that would return me all Locations for that customer. Instead, I'm always getting 0 results returned. Code is below, and I've also shown a screen shot of the Locations that exist for a test customer with ID 012349, and the debugger results showing 0 records returned.
Public Function GetAddressList(ByVal customerID As String) As String()()
Dim address As CR303010Content = m_context.CR303010GetSchema()
m_context.CR303010Clear()
Dim customerFilter As Filter = New Filter()
customerFilter.Field = address.LocationSummary.Customer
customerFilter.Condition = FilterCondition.Equals
customerFilter.Value = customerID
Dim searchfilters() As Filter = {customerFilter}
Dim searchCommands() As Command = {address.LocationSummary.Customer, address.LocationSummary.LocationID, address.GeneralInfoLocationAddress.AddressLine1, address.GeneralInfoLocationAddress.City}
Dim searchResult As String()() = m_context.CR303010Export(searchCommands, searchfilters, 0, False, False)
Return searchResult
End Function
Debugger showing searchResult array with a length of 0
I tried your example and couldn't get it to work using filters. I modified it slightly to pass the customerID in the search commands instead, and to add ServiceCommands.EveryLocationID to it to specify that we want system to loop through all locations:
Dim searchCustomer As New Value() With {.Value = customerID, .LinkedCommand = address.LocationSummary.BusinessAccount}
Dim searchCommands() As Command = {searchCustomer,
address.LocationSummary.ServiceCommands.EveryLocationID, address.LocationSummary.LocationID, address.GeneralInfoLocationAddress.AddressLine1, address.GeneralInfoLocationAddress.City}
Dim searchResult As String()() = screen.Export(searchCommands, Nothing, 0, False, False)

VBA Function - Argument Not Optional

Public Function RETURN_Equipment(Optional category As String) As Collection
Dim config As classConfiguration
Set config = New classConfiguration
Dim item As classItem
Set item = New classItem
Dim myCollection As Collection
Set myCollection = New Collection
For Each config In Configurations
For Each item In config.colItems
If IsMissing(category) Then
myCollection.add item
ElseIf InStr(category, "mainframe") <> 0 And item.category = "mainframe" Then
myCollection.add item
MsgBox "Fired!"
ElseIf category = "accessory" And item.category = "accessory" Then
Else
End If
Next
Next
RETURN_Equipment = myCollection
End Function
I keep getting
Compile error:
Argument not optional
I get the error on the last line
RETURN_Equipment = myCollection
I understand the error message, its telling me I did not fill out a parameter. But I only have one parameter, and I've declared it optional. It looks like the code thinks I'm trying to call the function from the function?
What gives?
Anytime you assign an object you need to use the set keyword.
set RETURN_Equipment = myCollection
I was getting this error because I was using the wrong function name when trying to return a result from a function. I was doing this:
Function MyFuncA(arg as String)
MyFuncB = arg 'The problem is I'm using MyFuncB instead of MyFuncA
End Function
This happened because I copied a function from somewhere else and changed the name, but not the return statement. This is not the OP's problem, but I was getting the same error message.
Because you've specified the Optional Parameter as a string it will default to an empty string if you've not specified a value.
This means it can't be missing
If you'd specified it as
Public Function RETURN_Equipment(Optional category) As Collection
It would be a variant and that could be missing, although you'd also be able to mess things up by passing non string variants as the category parameter
The best course of action is probably to replace
If IsMissing(category) Then
with
If category = "" Then
And as Brad has pointed out you'll need to use Set
Set RETURN_Equipment = myCollection
For full details check this
http://msdn.microsoft.com/en-us/library/office/gg251721%28v=office.15%29.aspx

Resources