Microsoft Access VBA invalid use of property error - vba

So, I have this class where I call a few classes where data is checked. They give back an error class, named Failcase. Now I get an error when I first set the error to true.
The error states:
Invalid use of Property.
Private Sub btnImport_Click()
Dim fail As Failcase
Set fail.Success = True '<---- This is where the error occures
Set fail = ImportCheckSpec(Me.txtImportSpec)
If fail.Success Then
MsgBox "Error " + CStr(fail.Code) + ": " + fail.Message, vbCritical, "Error"
Exit Sub
End If
Set fail = ImportCheckDate(Me.txtDateTime)
If fail.Success Then
MsgBox "Error " + CStr(fail.Code) + ": " + fail.Message, vbCritical, "Error"
Exit Sub
Else
MsgBox "Success"
End If
End Sub
The Failcase class looks like this:
Option Compare Database
Option Explicit
Public Success As Boolean
Public Code As Integer
Public Message As String
I use:
Microsoft Access 2013
VBA

You are using OOP without creating a new object of class Failcase. Try this in the module:
Option Explicit
Public Sub TestMe()
Dim fail As New failcase
fail.Success = True
Debug.Print fail.Success
End Sub
In the class:
Option Explicit
Private m_bSuccess As Boolean
Public Property Get Success() As Boolean
Success = m_bSuccess
End Property
Public Property Let Success(ByVal bNewValue As Boolean)
m_bSuccess = bNewValue
End Property
Thus, you would achieve encapsulation. With it, you may set a bit more rules for accessing your property - https://www.google.com/search?q=encapsulation+oop&oq=encapsulation+oop&aqs=chrome..69i57j0l5.3599j0j7&sourceid=chrome&ie=UTF-8
The code above was an example of early binding. This is another one, example of late binding, doing the same:
Public Sub TestLateBinding()
Dim fail As Object
Set fail = New failcase
fail.Success = True
Debug.Print fail.Success
End Sub
Early and late binding have different pros and cons.

It works like this.
Dim fail As New Failcase
fail.Success = True

Related

Set Access Module as a Public Variable

I'm trying to set an Access Module as a variable so that I can call certain functions using the variable name and not the actual module name. this will save me a lot of time changing the name of the called module in my forms.
I tried adding a Public variable 'Mod_ActiveModule' as seen below:
Public Str_FormLevel_01 As String
Public Str_FormLevel_02 As String
Public Str_FormLevel_03 As String
Public frm_FormLevel_01 As Form
Public frm_FormLevel_02 As Form
Public frm_FormLevel_03 As Form
Public Mod_ActiveModule As Module
Shown below is the Sub that I thought would set 'Mod_ActiveModule' to the Module named "Mod_Batches_DP_Pack" - BUT IT ISN'T WORKING!!!!
Private Sub cmd_Options_Click()
On Error GoTo ErrorHandler
Str_FormLevel_01 = "frm_Batches_04_DP_Pack"
Str_FormLevel_02 = "frm_Batches_04_DP_Pack_Edit"
Str_FormLevel_03 = "frm_Batches_04_DP_Pack_Edit_Detail"
Set frm_FormLevel_01 = Form_frm_Batches_04_DP_Pack
Set frm_FormLevel_02 = Form_frm_Batches_04_DP_Pack_Edit
Set frm_FormLevel_03 = Form_frm_Batches_04_DP_Pack_Edit_Detail
Set Mod_ActiveModule = Mod_Batches_DP_Pack
Call ActiveModule.SetUpContextMenu_Level_01
CommandBars("MenuOptions").ShowPopup
ExitHandler:
Exit Sub
ErrorHandler:
Debug.Print "Error: " & Err.Number & ": " & Err.Description
Debug.Print "Error On: " & Form.Name & " - cmd_Options_Click"
Resume ExitHandler
End Sub
Any help here would be greatly appreciated

Speech in PowerPoint (VBA)

I want to be able to make PowerPoint speak, say something.
I tried this code to make PP speak:
Private Sub CommandButton1_Click()
Application.Speech.Speak "Hello World"
End Sub
But the code doesn't work, it doesn't exists. What can I do, which is the right code?
It says:
Compile Error Method or Data member not found.
Sorry for any error on my question.
The reason it's not working is that there's no Application.Speech property/method in the PPT object model. Somewhere or other I've seen code that invokes Excel to do the lifting but here's an answer from John Wilson of PPT Alchemy that seems more direct:
There is a page on our site about talking message boxes
http://www.pptalchemy.co.uk/PowerPoint_speech.html
It could be easily modified to speak the text in a shape in Slide Show mode.
Sub speak(oshp As Shape)
Dim strSpeak As String
Dim SAPIObj As Object
Set SAPIObj = CreateObject("SAPI.SPvoice")
SAPIObj.Rate = -2
If oshp.HasTextFrame Then
If oshp.TextFrame.HasText Then
strSpeak = oshp.TextFrame.TextRange.Text
End If
End If
SAPIObj.speak "<pitch middle='-15'>" & strSpeak
End Sub
If you don't need to pick up the text from a particular shape, a modification along these lines should do it:
Sub SayThisAloud(sText as String)
Dim SAPIObj As Object
Set SAPIObj = CreateObject("SAPI.SPvoice")
SAPIObj.Rate = -2
SAPIObj.speak "<pitch middle='-15'>" & sText
End Sub
REgarding the MSDN page, it'll take some editing/modification to convert it to something a bit more useful. For example, here's an example of how you can get a list of the voices available:
In the declarations section:
Private V As Object
Private T As Object
Then
Sub ListVoices()
On Error GoTo EH
Dim strVoice As String
Dim SAPIObj As Object
Set SAPIObj = CreateObject("SAPI.SPvoice")
'Get each token in the collection returned by GetVoices
For Each T In SAPIObj.GetVoices
strVoice = T.GetDescription 'The token's name
'List1.AddItem strVoice 'Add to listbox
Debug.Print strVoice
Next
Exit Sub
EH:
If Err.Number Then ShowErrMsg
End Sub
Private Sub ShowErrMsg()
' Declare identifiers:
Dim T As String
T = "Desc: " & Err.Description & vbNewLine
T = T & "Err #: " & Err.Number
MsgBox T, vbExclamation, "Run-Time Error"
End
End Sub

VBA: Sub to Write to a Log File

I have a set of macros defined in my workbook, and I'd like to offer the user the option to log events related to those macros in a log file.
I initiate the log by creating the following in ThisWorkbook:
Public writeLog as Boolean
Public logWrite as Object
Public log as Object
Private Sub Worksheet_Open()
Dim prompt as Integer
prompt = MsgBox("Would you like to log events for this session?", vbYesNo, "Log Events?")
If prompt Then
writeLog = True
Set logWrite = CreateObject("Scripting.FileSystemObject")
Set log = logWrite.CreateTextFile("C:/TEST.txt", False)
Else
writeLog = False
End If
End Sub
I then created a procedure that I can use to write an argument to this object, which I've stored in its own module:
Public Sub PrintLog(obj as Object, argument as String)
If writeLog = True Then
obj.WriteLine argument
End If
End Sub
Unfortunately, this doesn't work, and I'm not sure why: even if I don't include obj as an argument to the function (since log and logWrite were created as global variables), I'm not able to Call WriteLog("String here.") or Call WriteLog(log, "String here.") without an error (Compile Error: Argument Not Optional.)
Is it possible to get such a Sub() to work, so that I can call it from anywhere in the workbook (after a button is pressed in a userform, for example) without having to define a new Scripting.FileSystemObject in every module?
I think that you can solve your problem by making some minor changes to your code. I tried the following setup:
logger module:
Option Explicit
Private log As Object
Public Sub initLog()
Dim prompt As VbMsgBoxResult
Dim fso As Object
prompt = MsgBox("Would you like to log events for this session?", vbYesNo, "Log Events?")
If prompt = vbYes Then
Set fso = CreateObject("Scripting.FileSystemObject")
Set log = fso.CreateTextFile("C:/TEST.txt", False)
End If
End Sub
Public Sub PrintLog(argument As String)
If Not log Is Nothing Then
log.WriteLine argument
End If
End Sub
Public Sub yadda()
'test
PrintLog "yadda"
End Sub
ThisWorkbook:
Private Sub Workbook_Open()
initLog
End Sub
This is my no-frills drop in replacement for Debug.Print(), that logs to "Log.txt" at your Workbook path.
To install : Just search and replace "Debug.Print" with "Log", and optionally call LogClear() at the start of your program.
Public Function Log(ByRef a_stringLogThis As String)
' send to TTY
Debug.Print (a_stringLogThis)
' append (not write) to disk
Open ThisWorkbook.path & "\Log.txt" For Append As #1
Print #1, a_stringLogThis
Close #1
End Function
OPTIONAL : And here's a helper you COULD call at the beginning of your to clear out the previous logs.
Public Function LogClear()
Debug.Print ("Erasing the previous logs.")
Open ThisWorkbook.path & "\Log.txt" For Output As #1
Print #1, ""
Close #1
End Function
OPTIONAL : Finally, if can't live without date and time in your logging, use this Log statement instead:
Public Function Log(ByRef a_stringLogThis As String)
' prepare date
l_stringDateTimeNow = Now
l_stringToday = Format(l_stringDateTimeNow, "YYYY-MM-DD hh:mm:ss")
' concatenate date and what the user wants logged
l_stringLogStatement = l_stringToday & " " & a_stringLogThis
' send to TTY
Debug.Print (l_stringLogStatement)
' append (not write) to disk
Open ThisWorkbook.path & "\Log.txt" For Append As #1
Print #1, l_stringLogStatement
Close #1
End Function
I believe you're having issues as writeLog already exists as a boolean. Error should be popping up "Ambiguous name detected"
Try the following,
Public bLog as Boolean
Public logWrite as Object
Public log as Object
Private Sub Worksheet_Open()
Dim prompt as Integer
prompt = MsgBox("Would you like to log events for this session?", vbYesNo, "Log Events?")
If prompt Then
bLog = True
Set logWrite = CreateObject("Scripting.FileSystemObject")
Set log = logWrite.CreateTextFile("C:/TEST.txt", False)
Else
bLog = False
End If
End Sub
Public Sub WriteLog(Optional obj as Object, Optional argument as String)
If bLog = True Then
obj.WriteLine argument
End If
End Sub
Edit: made parameters optional in WriteLog (or PrintLog) for further testing
' Write to a log file using Separator and Array of variant Parameters
' Auto generate the file
' USE EndLog to close
'use:
' PrintLog vbtab, "one", 2, 3
' PrintLog vbtab, "Apple","Windows","Linux","Android","Commodore","Amiga","Spectrum"
' EndLog
' Generate a csv file:
' PrintLog ";", rst!ID, rst!Name
Private FileLog As Object
Private fso As Object
Const DEBUG_LOG_FILE = "C:\log.txt"
Public Sub PrintLog(ByVal Separator As String, ParamArray Arguments() As Variant)
Dim ele As Variant
Dim line As String
If FileLog Is Nothing Then
Set fso = CreateObject("Scripting.FileSystemObject")
Set FileLog = fso.CreateTextFile(DEBUG_LOG_FILE, True, True)
End If
line = CStr(Now()) ' Print Timestamp
For Each ele In Arguments
If line > "" Then line = line & Separator
line = line & CStr(ele)
Next
If line > "" Then FileLog.WriteLine line
End Sub
Public Sub EndLog()
On Error Resume Next
FileLog.Close
Set FileLog = Nothing
Set fso = Nothing
On Error GoTo 0
End Sub

Trying to get value from an input file sheet throws Runtime Error '13': typemismatch

I'm new to VBA and I'm trying to access the files that I select with 2 GetOpenFilename, the thing is
I have my two GetOpenFilename inside
Private Sub Workbook_Open()
MsgBox "Please select Inventory File"
inventory = Application.GetOpenFilename("Text files(*.xlsx),*.xlsx", , "Please select Inventory File")
Set inventoryWorkbook = Application.Workbooks.Open(inventory)
MsgBox "Please select Material List File"
MaterialList = Application.GetOpenFilename("Text files(*.xlsx),*.xlsx", , "Please select Material List File")
Set materialListWorkbook = Application.Workbooks.Open(MaterialList)
Call Process(inventoryWorkbook, materialListWorkbook)
End Sub
and I'm trying to call the Sub Process that will handle both input files, this "Process" is in a module, at first I had this:
Call Process
and modified to Public Sub Process()
But that threw Runtime Error '424': Object Required
So I changed it to
Call Process(inventoryWorkbook, materialListWorkbook)
and Module:
Public Sub Process(inventoryWorkbook, materialListWorkbook)
MsgBox "Enters"
Set MaterialList_Main = materialListWorkbook.Worksheets("Sheet2")
Set MainProjectCode = MaterialList_Main.Range("B2").Value
MsgBox MainProjectCode
End Sub
but It throws Runtime Error '13': Type Mismatch, I have no idea where is the TypeMismatch or how to fix it. What am I doing wrong?
Use Option Explicit at the top of each module (also the Thisworkbook Module).
This will dramatically reduce the number of type mismatches.
Option Explicit
Dim MaterialList As String
Dim materialListWorkbook as Excel.Workbook
MaterialList = Application.GetOpenFilename("Text files(*.xlsx),*.xlsx", , "Please select Material List File")
Set materialListWorkbook = Application.Workbooks.Open(MaterialList)
Call Process(inventoryWorkbook)
And there is an error here:
Public Sub Process(inventoryWorkbook As Excel.Workbook, materialListWorkbook As Excel.Workbook)
dim MaterialList_Main as Excel.Worksheet
dim MainProjectCode as String
MsgBox "Enters"
Set MaterialList_Main = materialListWorkbook.Worksheets("Sheet2")
MainProjectCode = MaterialList_Main.Range("B2").Value 'Error: no Set for value!
MsgBox MainProjectCode
End Sub
The Set keyword is only used for objects, not regular variables.

Inter Process Communication using vbscript

I need to send data form one process to another.
Constraints :
Sender process is very expensive call.
It needs to be done using vbscipt.
For Sender process,this data transferring is an additional work.It shouldn't get affected much by this feature. There are around 1000 threads in a sender process in 4-5 mins.
Faster IPC is important.If it can be done asynchronoulsy it will be better.
I read about the named pipe.Is it possible to open a named pipe using vbscript .Also is there any other possible way considering the above constraints.
Using a named pipe is probably your only option from native VBScript. You could access any of the other IPC methods by writing a COM object in some other language.
A named pipe can be written to just like a file so you can use the FileSystemObject to open and read/write from a named pipe. The format for opening a named pipe is to use the format \\\\.\pipe\PipeName (Replace PipeName with the pipe's actual name).
So to write to a named pipe in VBScript:
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.CreateTextFile("\\.\pipe\PipeName", True)
a.WriteLine("This is a test.")
a.Close
Option Explicit
Dim g_receivedCallback
If WScript.Arguments.Named.Exists("NEW") Then
RunSecondInstance
Else
RunFirstInstance
End If
Sub RunSecondInstance()
Dim oSa, oWindow, oData, oCallback
' Search for the window
Set oSa = CreateObject("Shell.Application")
For Each oWindow In oSa.Windows
If TypeName(oWindow.Document) = "HTMLDocument" Then
If InStr(oWindow.Document.Title, "IPC Window") > 0 Then
' Get the data object, set a property and callback a method
Set oData = oWindow.GetProperty ("IPCData")
Set oCallback = oData.Callback
oData.Value = "Success!"
Call oCallback
End If
End If
Next
End Sub
Sub RunFirstInstance()
Dim oData, oIe, oWs
' Create a object to pass to a other script
Set oData = New IPCData
' Set a property to a callback method
Set oData.Callback = GetRef("MyCallback")
' Create a window and store the data in the window
Set oIe = CreateObject("InternetExplorer.Application")
oIe.Navigate "about:blank"
Do Until oIe.ReadyState = 4 : WScript.Sleep 5 : Loop
oIe.Document.Title = "IPC Window"
oIe.PutProperty "IPCData", oData
' Run second script instance
Set oWs = CreateObject("WScript.Shell")
oWs.Run "WSCRIPT.EXE """ & WScript.ScriptFullName & """ /NEW"
' Wait for callback from second script
Do Until g_receivedCallback = True : WScript.Sleep 5 : Loop
' Display received data
MsgBox oData.Value
' Close ie
oIe.Quit
End Sub
Sub MyCallback()
g_receivedCallback = True
End Sub
Class IPCData
Private m_callback
Public Property Get Callback()
Set Callback = m_callback
End Property
Public Property Set Callback(ByVal v)
Set m_callback = v
End Property
Private m_value
Public Property Get Value()
If IsObject(m_value) Then
Set Value = m_value
Else
Value = m_value
End If
End Property
Public Property Let Value(ByVal v)
m_value = v
End Property
Public Property Set Value(ByVal v)
Set m_value = v
End Property
End Class