I will keep it as short as possible. ( Please take into consideration , that I am not familiar with c# programming / dll and such things. I have been mostly working in the Data Analysis world with python )
I have a report in SSRS in Visual Studio that I would like to add some embedded code.
And i am trying to call those functions that are available for the SSRS
Microsoft Documentation states that for those functions you could call them by given the specific class.
for example
Math.Floor()
https://learn.microsoft.com/en-us/sql/reporting-services/report-design/custom-code-and-assembly-references-in-expressions-in-report-designer-ssrs?view=sql-server-ver15
. For convenience, you can view the most commonly used functions in the Expression dialog box, where they are listed by category: Text, Date and Time, Math, Inspection, Program Flow, Aggregate, Financial, Conversion, and Miscellaneous. Less commonly used functions do not appear in the list but can still be used in an expression.
I am trying to use the lookup function in the code
by calling Miscellaneous.Lookup
but somehow I get an error that this class does not exist.
do you have any idea where is the API/DEV Documentation related to this. I cannot really find any documentation reference to that function.
If I try with Math.Floor(1) it actually works
another a little bit more complex code
public function a(byVal x as Integer) as String
if(x = 1 ) then
Return Math.Floor(1)
else Return 2
end if
end function
EDIT: ( Thanks #Timothy G. )
Miscellaneous.Lookup(1,1,"holaInLookup","DataSet1")
Still same error
Related
VERY LONG story short, I'm trying to develop a MS Excel AddIn to allow an uneducated user (open to interpretation) to create Excel-based scripts that Visual Basic (yeah not C#) can essentially parse into the individual pieces and send to the browser via Selenium commands. So far, I've had quite a bit of success. Granted there is a little bit clunkiness, but this is round 1, and I've only been working with Selenium for a week.
Up to this point I have been able to use the CallByName function to call various Selenium methods where each _argument is passed from a higher level handler originating from values in spreadsheet cells.
Dim eleActionElement as Remote.RemoteWebElement = Nothing
eleActionElement = driver.FindeElement(By.Id("PresentObjectID"))
CallByName(eleActionElement, _strAction, CallType.Method, _strActionArg)
Initially I had problems with Bys:
Dim myBy As By = CallByName(By, _strBy, CallType.Method, _strByArg)
Intelisense warns that "By" is a class type and cannot be used as an expression. Fortunately, there are individual methods for each by type, so I have been able to retrieve elements effectively through:
Public Function DriverFindElementBy(_strBy As String, _strByArg As String) As Remote.RemoteWebElement
Dim strElementBy As String = "FindElementBy" & _strBy
Dim eleWebElement As Remote.RemoteWebElement = Nothing
eleWebElement = CallByName(ThisAddIn.driver, strElementBy, CallType.Method, _strByArg)
Return eleWebElement
End Function
Unfortunately, I haven't found a way to get ExpectedConditions to work. My best guess (of many) is:
Public Function WaitOnCondition(_strCondition As String, _strBy As String, _strByArg As String)
Dim myExpectedConditionObj As ExpectedConditions
CallByName(myExpectedConditionObj, _strCondition, CallType.Method)
waitDefault.Until(CallByName(myExpectedConditionObj, _strCondition, CallType.Method))
If strTestResult.Length = 0 Then
Return "Success"
Else
Return strTestResult.ToString
End If
End Function
Intelisense warns this could result in a NullReference and it does. I can see how the object is not instantiated yet, but the same approach worked with the RemoteWebElement. If studied the Selenium docs, and both are class types; so I'm left thinking the problem has to do with various methods of the ExpectedConditions and By classes take and return different numbers and types of arguments. It may be because both classes are delegates. It may be some simple error I'm making - although, I've written and rewritten these functions a dozen times with the recurring thought, "geez, this should work." One of those times you'd think I'd have blindly gotten it right.
I'm certainly not a .Net expert and advanced techniques can be baffling at times, but I do study the solutions people provide on SO and often have to go and expand my skills; so please know that nay help will be appreciate and will not go in vain.
One tiny request, if you give a C# (or Java or Python) explanation, just let me know if you KNOW / DON'T KNOW or AREN'T SURE if it will work in VB. My biggest challenge in advanced topics is that narrow segment of stuff that doesn't crossover between C# and VB.
THANKS in advance!
TL:DR; How can I compile a VB6 module file into a standard DLL which I can use across multiple VB6 applications?
I am tasked with the support of multiple legacy applications written in VB6.
All of these applications make use of piece of hardware constructed by my employer. Before I came on to work for my employer, he had outsourced the work of developing a DLL for the project to a company that is no longer capable of supporting it since the individual working for THEM recently quit and no one else is capable of figuring it out.
My employer has recently upgraded our hardware, so even worse - the DLL that Company furnished us with is no longer useful either.
Further exacerbated by the fact that the company who released to us the NEW hardware did not release to us a DLL file which is capable of running in VB6.
It now falls to me to create a DLL file ( NOT a device driver ) which is capable of facilitating communications between the new ( and hopefully the old ) devices and VB6 applications.
My knowledge of VB6 is... limited, at best. I am mostly familiar with .Net and have had much success in creating DLLs in .Net, but when it comes to VB6, I know enough to get by. I'm entering into uncharted territory here.
I'm well acquainted with the HID.dll and the SetupAPI.dll P/Invokes and structs necessary to make this work, and I was even fortunate enough to stumble upon this, which had a working bit of VB6 code which facilitates read/writing to/from HIDs connected to the system. I tested this and ( with a bit of fidgeting ) it worked for our device out of the box. But that doesn't help me because I can't compile the module into a DLL file ( let alone figuring out events in VB6 and a truck load of other things, but I'm getting ahead of myself ).
I've read and tried a few different methods and while they proved promising, they didn't work.
Google has also inundated me with a lot of red herrings and been in general not very helpful.
If necessary, I would even write it in C/C++ ( though I'd rather not if there is some other way ).
So is what I am trying to do possible? Can someone direct me to some step-by-step for this sort of thing?
EDIT 1 :
To expound a bit, when I say that "they didn't work", what I mean is that in the case of the first link, the program still failed to find the function ( with an error message like "Function entry point not found" ) and in the second case I consistently and repeatedly received a memory write error when trying to call the function ( not fun ).
Here's a link to a way to do a standard DLL, that looks more straightforward than the links you've posted. I can say that if Mike Strong ("strongm") posts code, it works, too. You might want to have a look at it.
However, it's probably better to use COM if you're able: it's easier to set up (obviously) and it also has some standard capabilities for keeping track of the object's interface, that are built into VB6. For example, when you use the TypeOf keyword, VB6 actually makes an internal call to the object's QueryInterface method, which is guaranteed to exist as one of the rules of COM (and, if you use the keyword on a reference to a standard DLL object you'll get an error).
VB6 does "static" classes by setting the class's Instancing property to GlobalMultiUse. Warning: the "static" keyword has an entirely different meaning in VB6: static local variables' values persist between method calls.
1. After your trip to 1998 to get your copy of VB6, start a new ActiveX DLL project:
2. Edit Project Properties for the name of the beast.
3. Add a Class for the interface you are creating. I cleverly named the class VB6Class because the project/DLL is named VB6DLL.
4. Write code. I added some test methods to perform complex calculations:
Option Explicit
Public Function GetAString(ByVal index As Integer) As String
Dim ret As String
Select Case index
Case 0
ret = "Alpha"
Case 1
ret = "Beta"
Case Else
ret = "Omega"
End Select
GetAString = ret
End Function
Public Function DoubleMyInt(ByVal value As Integer) As Integer
DoubleMyInt = (2 * value)
End Function
Public Function DoubleMyLong(ByVal value As Long) As Long
DoubleMyLong = (2 * value)
End Function
5. Make DLL from File menu. You may need to be running As Admin so it can register the DLL.
6. In the project which uses it, add a reference to the DLL.
Test code:
Private Sub Command1_Click()
Dim vb6 As New VB6DLL.VB6Class
Dim var0 As String
Dim var1 As Integer
Dim var2 As Long
var0 = vb6.GetAString(0)
var1 = vb6.DoubleMyInt(2)
var2 = vb6.DoubleMyLong(1234)
Debug.Print "GetAString == " & var0
Debug.Print "DoubleMyInt == " & var1
Debug.Print "DoubleMyLng == " & var2
End Sub
Result:
GetAString == Alpha
DoubleMyInt == 4
DoubleMyLng == 2468
Not sure what to do about the "truck load of other things".
I'm making a batch development kit in visual basic and i need to be able to call a function that sets textboxes to a saved files text. How do i do this without returning? I tried this, and it lets me run the program, but gives me a warning, not an error. How do i go about doing this? Here is my little function design. P.S. I recently switched back to VB from Java and i'm so used to doing public void. Thanks in advance!
Public Function loadProject()
End Function
You want a Sub, which is the equivalent to the Java void method.
Public Sub LoadProject()
End Sub
It's not a bad Idea to just have a function that returns a value like a success statement just in case you need it. A call to the function doesn't have to accept or use the return value from the function.
You could even build a class with two values - txtpreviousvalue and txtnewvalue
Have your function return that type and fill an instance of the type with the respective values.
One day, if you need it, you'll have it.
P.S. I'm only posting this as an answer because the good answer posted by sstan is not marked as the answer; You should probably do that.
Is it possible to create variables to be a specific type in Lua?
E.g. int x = 4
If this is not possible, is there at least some way to have a fake "type" shown before the variable so that anyone reading the code will know what type the variable is supposed to be?
E.g. function addInt(int x=4, int y=5), but x/y could still be any type of variable? I find it much easier to type the variable's type before it rather than putting a comment at above the function to let any readers know what type of variable it is supposed to be.
The sole reason I'm asking isn't to limit the variable to a specific data type, but simply to have the ability to put a data type before the variable, whether it does anything or not, to let the reader know what type of variable that it is supposed to be without getting an error.
You can do this using comments:
local x = 4 -- int
function addInt(x --[[int]],
y --[[int]] )
You can make the syntax a = int(5) from your other comment work using the following:
function int(a) return a end
function string(a) return a end
function dictionary(a) return a end
a = int(5)
b = string "hello, world!"
c = dictionary({foo = "hey"})
Still, this doesn't really offer any benefits over a comment.
The only way I can think of to do this, would be by creating a custom type in C.
Lua Integer type
No. But I understand your goal is to improve understanding when reading and writing functions calls.
Stating the expected data type of parameters adds only a little in terms of giving a specification for the function. Also, some function parameters are polymorphic, accepting a specific value, or a function or table from which to obtain the value for a context in which the function operates. See string.gsub, for example.
When reading a function call, the only thing known at the call site is the name of the variable or field whose value is being invoked as a function (sometimes read as the "name" of the function) and the expressions being passed as actual parameters. It is sometimes helpful to refactor parameter expressions into named local variables to add to the readability.
When writing a function call, the name of the function is key. The names of the formal parameters are also helpful. But still, names (like types) do not comprise much of a specification. The most help comes from embedded structured documentation used in conjunction with an IDE that infers the context of a name and performs content assistance and presentations of available documentation.
luadoc is one such a system of documentation. You can write luadoc for function you declare.
Eclipse Koneki LDT is one such an IDE. Due to the dynamic nature of Lua, it is a difficult problem so LDT is not always as helpful as one would like. (To be clear, LDT does not use luadoc; It evolved its own embedded documentation system.)
Using VB.net, the following snippet gives the error below.
Dim _account = Account.Find(Function(x As Account) x.AccountName = txtFilterAccountName.Text)
or similarly if I do
.SingleOrDefault (Function(x As Account) x.AccountName = txtFilterAccountName.Text)
will both give the error "The method 'CompareString' is not supported". If I make the same call searching for an integer (ID field) it works fine.
.SingleOrDefault (Function(x As Account) x.Id = 12)
So integer matching is fine but strings don't work Is this a problem with the VB.net templates?
No this is not a problem with Vb.Net templates.
The problem is that you are not using a normal LINQ provider. Based on your tag (subsonic) I'm guessing you're using a LINQ to SQL query.
The problem is that under the hood, this is trying to turn your code into an expression tree which is then translated into an SQL like query. Your project settings are turning your string comparison into a call in the VB runtime. Specifically, Microsoft.VisualBasic.CompilerServices.Operators.CompareString.
The LINQ2SQL generater in question or VB compiler (can't remember where this check is done off the top of my head) does not understand how to translate this to an equivalent bit of SQL. Hence it generates an error. You need to use a string comparison function which is supported by LINQ2SQL.
EDIT Update
It looks like the CompareString operator should be supported in the Linq2SQL case. Does subsonic have a different provider which does not support this translation?
http://msdn.microsoft.com/en-us/library/bb399342.aspx
The problem is with SubSonic3's SQL generator and the expression tree generated from VB.NET.
VB.NET generates a different expression tree as noted by JaredPar and SubSonic3 doesn't account for it - see Issue 66.
I have implemented the fix as described but it has yet to merge into the main branch of SubSonic3.
BlackMael's fix has been committed:
http://github.com/subsonic/SubSonic-3.0/commit/d25c8a730a9971656e6d3c3d17ce9ca393655f50
The fix solved my issue which was similar to John Granade's above.
Thanks to all involved.