How to obtain data type directly? [duplicate] - excel

Is there a way to determine the Object type, when passing a reference to a function?
I'm using a security permissions function, which determines if the user has permission to view/edit the Form passed to it by reference. I'd like to expand this to include reports as well.
To keep the function generic, I'd like to pass a ref for either a Form or a Report as an Object, eg:
function gfSecurity_Permission(obj as Object)
However, I'd need to determine the type of the object within the function.
Does anyone know of a way to do that?
MTIA

Take a look at
typeOf and typeName
Generic object variables (that is, variables you declare as Object)
can hold objects from any class. When using variables of type Object,
you may need to take different actions based on the class of the
object; for example, some objects might not support a particular
property or method. Visual Basic provides two means of determining
which type of object is stored in an object variable: the TypeName
function and the TypeOf...Is operator.
TypeName and TypeOf…Is
The
TypeName function returns a string and is the best choice when you
need to store or display the class name of an object, as shown in the
following code fragment:
Dim Ctrl As Control = New TextBox
MsgBox(TypeName(Ctrl))
The TypeOf...Is operator is the best choice for testing an object's
type, because it is much faster than an equivalent string comparison
using TypeName. The following code fragment uses TypeOf...Is within an
If...Then...Else statement:
If TypeOf Ctrl Is Button Then
MsgBox("The control is a button.")
End If

Simplest way to determine the access type in access is to do an object lookup within the Access' system tables.
Here would be the lookup:
DLookup("Type","MSysObjects","NAME = '" & strObject & "'")
strObject is the name of the object within Access
The result is one of the number below OR NULL if the object does not exist in Access
1 = Access Table
4 = OBDB-Linked Table / View
5 = Access Query
6 = Attached (Linked) File (such as Excel, another Access Table or query, text file, etc.)
-32768 = Access Form
-32764 = Access Report
-32761 = Access Module
so, the dlookup would provide "-32768" for a Form or "-32764" for a Report
Hope that helps

Related

How to use EncodedObjectAsID?

I'm trying to understand get_instance_id()
and I came across this line in the documentation:
This ID can be saved in EncodedObjectAsID, and can be used to retrieve
the object instance with #GDScript.instance_from_id.
I can't seem to understand what this statement means exaclty and how to use EncodedObjectAsID, could someone please provide a working example?
The EncodedObjectAsID follows a pattern called Boxing. Boxing is where you put a primitive value, like an int, into an object. This boxed primitive can now be used in an object oriented way. For example, you can pass the boxed int to a function that only takes objects (i.e. it applies Polymorphism):
func only_takes_object(obj: Object)
only_takes_object(123) # Error
var box = EncodedObjectAsID.new()
box.object_id = 123
only_takes_object(box) # Valid
This is how parts of the editor use the EncodedObjectAsId object.
In marshalls.cpp we can see that an encoded Object may be an integer ID or the whole object. When it is flagged as only an integer ID a EncodedObjectAsID object is created. This object is then converted to a Variant.
When adding a stack variable in editor_debugger_inspector.cpp a variant with a type of object is assumed to be and converted to an EncodedObjectAsID to fetch the referenced object's id.
Here's two more links that follow a similar pattern:
array_property_edit.cpp
scene_debugger.cpp
Note that Variant can be implicitly converted to an Object and Object::cast_to() only takes Objects.
This ID can be saved in EncodedObjectAsID, and can be used to retrieve the object instance with #GDScript.instance_from_id.
This sentence should be split into two independent clauses. It should read as
"The instance ID can be saved in an EncodedObjectAsID."
"The instance ID can be used to retrieve the object instance with #GDScript.instance_from_id()."
Note: You should not store an object's id in storage memory. There is no guarantee that an object's id will remain the same after restart.

How to store any class object in an hash map

I have a hash map which acts as store of objects - where key is class name & value is object
store = {} of String => Type
store["Animal"]= Animal.new
store["Book"]= Book.new
store["Car"]= Car.new
Here class is unknown to me, which means i can't use union type. Please tell me how to solve this problem ?
I am trying to create a wrapper around hash map for storage of objects, which will save object & return object by key.
Update 1
Classes will be passed as a parameter - like this
add_in_store(Animal)
add_in_store(Person)
Update 2
Crystal play link of what i am trying to do - https://play.crystal-lang.org/#/r/8lwx
Solution of problem doesn't have to be in same way as what i m doing. It can be with any other approach like using proc or macro etc.
Hash is a generic type, to wrap it in a way where you cannot or don't want to restrict the possible types of the generic arguments, you should make your wrapper itself generic.
class Store(V)
#store = {} of String => V
def add(name, value : V)
#store[name] = value
end
end
Then the consumer of your wrapper has to give the possible types.

Late Binding a UDT in a form module to pass as a parameter

I have an access database and I'm attempting to write some VBA to increase automation.
I have a module I've entitled Global Variables which I've successfully used to define global constants (file paths etc) and a module ReportCode which has two main subrouties, one to run a query with ADODB (scraping form params where needed - returning a recordset), and a second which takes this record set and writes the data out to an excel template.
Given I may want to have multiple queries write to multiple tabs I thought the best way was to define a ExportDocument object to contain common parameters and a OrgReport object, containing query and tab specific parameters - then gather multiple OrgReport objects in a collection.
I'd hope to then pass just these two parameters into the main subroutine. This turns out to be a pain in VBA (or at least compared to ruby!).
Here you can see how I've defined by custom objects
Option Private Module
' Define Custom Doc Object
Public Type ExportDocument
TeamName As String
TemplatePath As String
SaveName As String
SavePath As String
End Type
' Define Custom Report Object
Public Type OrgReport
Query As String
Fields As Variant
Sheet As String
StartCol As Integer
StartRow As Integer
Headers As Boolean
End Type
And here is the code in my form which then called an additional module which does the heavy lifting - I know that part works because it did before I tried to go all OOP on this...
Private Sub my_report_from_form_Click()
' Prep Query Inputs
Dim TeamX_Report As OrgReport
TeamX_Report.Query = "qry_TeamReporting Query"
TeamX_Report.Sheet = "RawData"
TeamX_Report.StartCol = 1
TeamX_Report.StartRow = 2
TeamX_Report.Headers = True
TeamX_Report.Fields = Nothing
' Prep Document Inputs
Dim Teamx_Doc As ExportDocument
Teamx_Doc.TeamName = "MyTeam"
Teamx_Doc.TemplatePath = strReportTemplatePath & "MyTeam.xltm"
Teamx_Doc.SaveName = ""
Teamx_Doc.SavePath = strReportSavePath & Teamx_Doc.TeamName
' Init and set collection for CHAIN reports
Dim TeamReports As New Collection
TeamReports .Add Item:=TeamX_Report, Key:=TeamX_Report.Query
Call export_data_dump(Teamx_Doc, TeamReports)
End Sub
This gives me the issue of:
Only public user defined types defined in public object modules can be
used as parameters or return types for public procedures of class
modules or as fields of public user defined types
Following advice here I changed
Dim Teamx_Doc As ExportDocument
to
Teamx_Doc = CreateObject("ExportDocument")
But alas now i get
Run-time error '429': ActiveX component can't create object VBA
All references to this problem seem to be related to calling code from the Word., Excel. or Outlook. codebases, so perhaps I'm just missing a prefix for my own module stored within my database?
Best lead I've found is this one, which seems to suggest there's deeper issues with what i'm trying to do, or that i may get around parts by calling Friend, though I'm lost to where and how.
Is there a way I can late bind my UDT Objects within my form code, stash one in a collection then pass both to a subroutine that will be able to grab params from the first 'Doc' object and then iterate through the second 'report' object?
VBA >_<
There's no reason I can see why this doesn't work:
Dim Teamx_Doc As ExportDocument
Especially if you're not getting an error on line
Dim TeamX_Report As OrgReport
I've used custom Public Types before - no need for CreateObject
Though the docs seem to say it's just fine, can you try removing the
Option Private Module
The error message is kinda misleading. You simply can't put variables with an User-defined Type into a collection.
Option 1: Use an array instead. This actually sounds like it would work well for what you want to do.
Option 2: Create a class module instead of an UDT for OrgReport. Then instantiate objects of that class, those you can add to a collection.
See
Excel VBA Collections and Custom Data Types
and
http://www.mrexcel.com/forum/excel-questions/16849-adding-user-defined-types-collection.html

Excel VBA - How to convert an Object into a String

I like to convert an Object into a string. I found this topic but I can not get it to work in Excel 2010 ("Cast.xxx", "CArray()" and "Array()" seems to be unknown to Excel?)
I know how to convert a variant e.g. "toString = CStr(x)" but not how to do it the best way for an object
Function toString(ByVal x As Variant) As String
If TypeOf x Is Object Then
toString = ???
Else
toString = CStr(x)
End If
End Function
any suggestions?
Are you referring to the IFormattable interface. For example in VB.NET?
Excel VBA isn't a language that will provide you with a ToString method since it doesn't support inheritance.
In your example, you are simply converting whatever the variant is to a string, but an object in VBA wont support this directly.
If you have an external COM object, this would need to be exposed in the interface to access this method to call it from VBA.
For your own classes, you could implement your own IFormattable interface for your objects, but you would have assign to that interface before being able to call the objects ToString method - possible with a helper method. You could of course just supply a ToString method for every class which will through the class interface, but if you want to include this functionality for all objects, then an interface is probably the way to go.
Hope that helps.

Casting to types that are know only at Runtime by their string names. C#

I've got a problem here. (C#)
There's a collection in another assembly (I cannot change it) that takes a string as parameter and returns an object.
Like:
object Value = ThatCollection.GetValue("ParameterName");
The problem is, for each parameter string, it returns a DIFFERENT type as object.
What I want is to cast those objects to their respective types, knowing the types only at runtime by their string names.
I need to do some operations with those returned values.
And for that I need to cast them properly in order to access their members and so.
Limitations:
I cannot use "dynamic" since my code needs to be done in an older framework: 3.5 (because of interop issues).
I need to do operations with MANY returned values of different types (no common interfaces nor base classes, except "object", of course)
All I have is a table (containing string values) correlating the parameter names with their returned types.
Yes, I could transform that table into a biiig "switch" statement, not very nice, don't want that.
Any hints??
You want to look into reflection, something like the following should work to cast an object to type T. Set up a simple cast method:
public static T CastToType<T>(object o)
{
return (T)o;
}
Invoke this using reflection:
Type t = Type.GetType(stringName)
MethodInfo castTypeMethod = this.GetType().GetMethod("CastToType").MakeGenericMethod(t);
object castedObject = castTypeMethod .Invoke(null, new object[] { obj });

Resources