I don't have any experience programming with VBScript and I'd like to use some OOP approach. If you'll look at my code below, you will see that I'm trying to create DB access class with a set of methods, that returns data sets. Have no idea why, but receiving error:
Microsoft VBScript runtime error '800a01c2'
Wrong number of arguments or invalid property assignment
/TrashCan/library/BLL/CreditBLLClass.asp, line 18
I have an .asp page:
<body>
<!-- #INCLUDE FILE="library\BLL\CreditBLLClass.asp" -->
<%
Dim creditBLL
Dim reader
creditBLL = new CreditBLLClass
reader = creditBLL.GetData()
If reader.EOF = False Then
Do While reader.EOF = False
Response.Write(reader.Fields("a").Value)
reader.MoveNext
Loop
End If
%>
</body>
CreditBLLClass.asp:
<!-- #INCLUDE FILE="DatabaseConnectionClass.asp" -->
<%
Class CreditBLLClass
'Private variables
Dim connection
Public Default Function Init()
Set Init = Me
End Function
Public Function GetData ()
connection = new DatabaseConnectionClass
GetData = connection.DBGetRecords("select a from b")
End Function
End Class
%>
And database connection class
<%
Class DatabaseConnectionClass
'Private variables
dim pConnection
Public Default Function Init()
Set Init = Me
End Function
Public Function DBGetRecords ( sSQL )
Set pConnection = Server.CreateObject( "ADODB.Connection" )
With pConnection
.ConnectionString = "string"
.Open
End With
DBGetRecords = pConnection.Execute ( sSQL )
End Function
End Class
%>
Please tell me what am I doing wrong? Maybe there is a common approach of how to build data access layer?
The error is in the invalid property assignment part of the error.
From your code:
connection = new DatabaseConnectionClass
GetData = connection.DBGetRecords("select a from b")
You have to use Set when using objects.
Change it to this:
Set connection = new DatabaseConnectionClass
Set GetData = connection.DBGetRecords("select a from b")
Related
I'm working on some code working with MS Access database in VBA 6. My goal is to make this same code working with PostgreSQL too (this means it should be able to work with both) . The code is working with DAO.DBEngine but I've not found a way to make this class connect to a PostgreSQL database. My solution is to create an other class with the same methods as DAO.DBEngine, for example the original code is using TableDefs and when I'm create a function called TableDefs I got "ambiguous name detected". Is there any way to name two methods class the same or to suppress/avoid this "ambiguous name detected" error ?
Based on the information provided in the link you could create three classes
IDatabase
Option Explicit
Function Hello()
End Function
clsDBAccess
Option Explicit
Implements IDatabase
Function IDatabase_Hello()
MsgBox TypeName(Me)
End Function
clsPostSQL
Implements IDatabase
Function IDatabase_Hello()
MsgBox TypeName(Me)
End Function
And you could use it like that
Option Explicit
Sub Main()
Dim myType As String
Dim oDatbase As IDatabase
' Determine myType
myType = "Access"
' myType = "PostSQL"
Set oDatbase = ClassFactory(myType)
' Your code here
oDatbase.Hello
End Sub
Function ClassFactory(dbType As String) As IDatabase
Dim oDatabase As IDatabase
If dbType = "Access" Then
Set oDatabase = New clsDBAccess
ElseIf dbType = "PostSQL" Then
Set oDatabase = New clsPostSQL
End If
Set ClassFactory = oDatabase
End Function
I'm writing a project where this will be extended with further modules later on, and as such i want as much of the code as possible to be independent, so I'm using various methods to keep everything as generic as possible, and not require hard-coding lists of types, classes etc.
As a Proof of concept, I've come up with the following code in a class;
Public Class clsAddition
Public Function DoAction(Value1 As String, Value2 As String) As String
Dim dblTmpRet As Double
Dim strTmpRet As String = ""
If IsNumeric(Value1) = False Then strTmpRet += "Argument 'Value1' is not numeric. "
If IsNumeric(Value2) = False Then strTmpRet += "Argument 'Value2' is not numeric. "
If strTmpRet = "" Then
dblTmpRet = CDbl(Value1) + CDbl(Value2)
strTmpRet = CStr(dblTmpRet)
End If
Return strTmpRet
End Function
Private Function IsNumeric(Input As String) As Boolean
Dim blnTmpRet As Boolean
Try
Dim dblTest As Double = CDbl(Input)
blnTmpRet = True
Catch ex As Exception
blnTmpRet = False
End Try
Return blnTmpRet
End Function
Public Sub New()
MyBase.New()
End Sub
End Class
And the following code in a windows form;
Private objObjectClass As Object
Private Sub cmdCreateObject_Click(sender As Object, e As EventArgs) Handles cmdCreateObject.Click
Dim assem As Assembly = GetType(Form1).Assembly
Dim typChosen As Type
Try
typChosen = assem.GetType(Me.comObjectType.SelectedItem.ToString, True)
Catch ex As Exception
typChosen = Nothing
End Try
If Not IsNothing(typChosen) Then
'found it
objObjectClass = Activator.CreateInstance(typChosen, True)()
Else
'didn't find it
Throw New Exception("Unable to locate type in assembly")
End If
End Sub
The issue is, that on the "Activator.CreateInstance(typChosen, True)()" line, the following error is thrown
An unhandled exception of type 'System.MissingMemberException'
occurred in Microsoft.VisualBasic.dll Additional information: No
default member found for type 'clsAddition'
The aim is for me to be able to create instances of classes, then call a known name function on them. In this example, I'd create another class called "Divide", or another one that was called "Concatinate" etc, however in the real program these classes will all perform very different actions, have different properties, methods etc, with this one function ("DoAction" in the above example) sharing a syntax and return type.
Please help! been banging my head on this for a while now!
TIA!
As Per Hans Passant comment, this is due to the extra parenthesis on the following line;
Activator.CreateInstance(typChosen, True)()
Changing this to ;
Activator.CreateInstance(typChosen, True)
resolves the issue.
I have a module class file "CombinaisonLine" in my class modules folder :
Private pAdult As String
Private pChild As String
Public Property Get Adult() As String
Adult = pAdult
End Property
Public Property Let Adult(Value As String)
pAdult = Value
End Property
Public Property Get Child() As String
Child = pChild
End Property
Public Property Let Child(Value As String)
pChild = Value
End Property
In my modules folder, I have a function called when I click on a button in my sheet :
Function Test()
Dim Line As CombinaisonLine
If (Sheets("Feuil1").Cells(3, 6).Value = "YES") Then
Line.Adult = "1"
Line.Child = "0"
End If
End Function
I am getting an error 91 at line "Line.Adult="1"" with the following message (I am using a french version, so I have translated the message into english):
execution error "91":
Object variable or Bloc variable With not defined
I don't know what I am missing. Thanks in advance for your help
You need to create object of class CombinaisonLine first, and destroy when you do not need it:
Function Test()
Dim Line As CombinaisonLine
Set Line = New CombinaisonLine
If (Sheets("Feuil1").Cells(3, 6).Value = "YES") Then
Line.Adult = "1"
Line.Child = "0"
End If
Set Line = Nothing
End Function
I get the following error Class 'PropGenie_WebService.Branch' cannot be indexed because it has no default property. And I am not sure why. I have googled but don't get a proper explanation or fix. C# help welcome.
My code in the branch.vb class:
Public Function Update() As Branch
Return Update(Me, Path) 'error at update.
End Function
And in my Base class (Resources.vb) I have:
Public Shared Function Update(Of T As {Resources, New})(resource As T, path As String) As T
Dim request = CreateRequest(path & "/{id}", Method.PATCH)
request.AddUrlSegment("id", resource.Id.ToString(CultureInfo.InvariantCulture))
request.AddBody(resource)
Dim Client = CreateClient()
Dim responce = Client.Execute(Of T)(request)
If responce.StatusCode <> HttpStatusCode.OK Then
Throw New InvalidOperationException("Update Failed" & Convert.ToString(responce.StatusCode))
End If
Return responce.Data
End Function
You need to specify the class in which the shared function is also, or it will try to use the Update function in the object you are in.
Public Function Update() As Branch
Return Resources.Update(Me, Path)
End Function
I am getting a Object not set to an instance of object error. I have put a list view where all messages should be shown. I am using lumisoft sample code which I ported to vb.net
Private Sub FillMessagesList()
Me.Cursor = Cursors.WaitCursor
Try
Dim m_pPop3 As POP3_Client = Nothing
For Each message As POP3_ClientMessage In m_pPop3.Messages
Dim mime As Mail_Message = Mail_Message.ParseFromByte(message.HeaderToByte())
Dim item As New ListViewItem()
If mime.From IsNot Nothing Then
item.Text = mime.From.ToString()
Else
item.Text = "<none>"
End If
If String.IsNullOrEmpty(mime.Subject) Then
item.SubItems.Add("<none>")
Else
item.SubItems.Add(mime.Subject)
End If
item.SubItems.Add(mime.[Date].ToString())
item.SubItems.Add(CDec(message.Size / CDec(1000)).ToString("f2") & " kb")
item.Tag = message
ListView1.Items.Add(item)
Next
Catch x As Exception
MessageBox.Show(Me, "Errorssssss: " + x.Message)
End Try
Me.Cursor = Cursors.[Default]
End Sub
The problem is here:
Dim m_pPop3 As POP3_Client = Nothing
For Each message As POP3_ClientMessage In m_pPop3.Messages
You set m_pPop3 to Nothing and then try to access one of its members.
You say that you ported the code - perhaps you need to look back at the original code and port it correctly:
private POP3_Client m_pPop3 = null;
/// <summary>
/// Default constructor.
/// </summary>
public wfrm_Main()
{
InitUI();
this.Visible = true;
wfrm_Connect frm = new wfrm_Connect(
new EventHandler<WriteLogEventArgs>(Pop3_WriteLog));
if(frm.ShowDialog(this) == DialogResult.OK){
m_pPop3 = frm.POP3;
// etc...
}
private void FillMessagesList()
{
this.Cursor = Cursors.WaitCursor;
try{
foreach(POP3_ClientMessage message in m_pPop3.Messages){
// etc...
}
}
Notice that m_pPop3.Messages is a private member here, not a local variable as you have implemented it.
To correct your code I would suggest changing it to be more similar to the original. Change the local variable to a private member and set it in the constructor, just as the original C# code does.
The culprit is possibly from the code in the 2 lines:
Dim m_pPop3 As POP3_Client = Nothing
For Each message As POP3_ClientMessage In m_pPop3.Messages
You're trying to loop through the messages in "m_pPop3" but you've explicitly set it to nothing on the line directly above.
I'm guessing it's here since you're setting m_pPop3 to Nothing. If you'd stepped through the code it would show you that.
Dim m_pPop3 As POP3_Client = Nothing
For Each message As POP3_ClientMessage In m_pPop3.Messages