Runtime error '91' on visual basic for executing matlab .m file - matlab

I want to call matlab & at the same time run .m file from visual basic 6. but I'm getting this run-time error '91', variable not set bla bla. I've searched the internet to find any solution but I couldn't. There is something wrong with my code, I don't know what it is. can anyone please check & see what's wrong?
Private Sub Form_Load()
Dim MatLab As Object
Dim Result As String
Dim MReal(1, 3) As Double
Dim MImag(1, 3) As Double
Dim mat_exe As String
Dim mat_io_folder As String
Dim mat_m As String
mat_exe = "G:\matlab\bin\matlab.exe"
mat_io_folder = "G:\Farin\New folder"
mat_m = "Untitled.m"
FileName = mat_exe & " " & "addpath('mat_io_folder') & mat_m" & " -s1"
runmatlab = Shell(FileName, 1)
Result = MatLab.Execute("cd G:\Farin\New folder")
Result = MatLab.Execute("Untitled")
'Calling m-file from VB
'Assuming solve_bvp exists at specified location
'Result = MatLab.Execute("cd G:\Farin\New folder\Untitled")
End Sub

Error 91 in VB6 means object variable not set, which, at a guess, would be the statement
result = MatLab.Execute("...")
Matlab is declared as an object but it has not been assigned a value. List of VB6 runtime errors can be found in https://msdn.microsoft.com/en-us/library/aa264975(v=VS.60).aspx
Another problem is the Filename assignment. It should read
FileName = mat_exe & " " & "addpath('" & mat_io_folder & "') " & mat_m & " -s1"
Might be an idea to MsgBox Filename before running the shell command.

Related

How to edit all word documents in a directory?

I've been given the scut job of correcting some hundred or so code testing reports that have been filled out incorrectly by a senior coder who has more import work to do.
Unluckily for me all the files are ms-word documents. But luckily for the formatting is all the same and the errors are all made in the same cells in the same table.
In the past I wrote a bash to edit to change single quotes to double quotes on multiple xml files. But that was with a linux machine. This time around I have only a window machine.
Any hints where to begin?
The answer was to use VBA. I built two subroutines.
The first subRoutine loops through the directory and
opens each *.doc file it finds. Then on the open document file it calls
the second subRoutine. After the second subRoutine is finished the document
is saved and then closed.
Sub DoVBRoutineNow()
Dim file
Dim path As String
path = "C:\Documents and Settings\userName\My Documents\myWorkFolder\"
file = Dir(path & "*.doc")
Do While file <> ""
Documents.Open FileName:=path & file
Call editCellsTableRow2
ActiveDocument.Save
ActiveDocument.Close
file = Dir()
Loop
End Sub
~~~~~~
The second subRoutine only works if all documents have the same formating.
For example: The second row of the only table in the document has cells numbered 6, 7, 8. These contain "dd/MM/yyyy" , "Last Name", "First Name"
These cells need to be changed to "yyyy/MM/dd", "Surname", "Given Name"
Sub editCellsTableRow2()
Application.ScreenUpdating = False
Dim Tbl As Table, cel As Cell, i As Long, n As Long
With ActiveDocument
For Each Tbl In .Tables
Tbl.Rows(2).Alignment = xlCenter
For Each cel In Tbl.Rows(2).Cells
If cel.ColumnIndex = 6 Then
cel.Range.Text = vbCrLf + "yyyy/MM/dd"
End If
If cel.ColumnIndex = 7 Then
cel.Range.Text = vbCrLf + "Surname"
End If
If cel.ColumnIndex = 8 Then
cel.Range.Text = vbCrLf + "Given Name"
End If
Next cel
Next Tbl
End With
Set cel = Nothing: Set Tbl = Nothing
Application.ScreenUpdating = True
End Sub

Subform to search record on main form

I have a subform like so:
When i click the 'select' button, i wish for the record on the main form to navigate to the appropriate one (the one which holds the same Staff ID).
What I have tried so far is for when the button is pressed to run the following vba:
Private Sub Command6_Click()
Dim rs As Object
Dim strLinkValue As String
strLinkValue = Forms![navigation form]![NavigationSubform]![teacher search qry subform]![Staff ID].Value
Set rs = Forms![navigation form]![NavigationSubform]![teacher search qry subform].Form.RecordsetClone
rs.FindFirst "[Staff ID] = '" & strLinkValue & "'"
Forms![navigation form]![NavigationSubform].Bookmark = rs.Bookmark
End Sub
But when I do this I get run-time error 438 (object doesn't support this property or method).
Any ideas? I feel like I'm over-complicating things.
You first got error 438 ("Object doesn't support this property or method.") at this line ...
Set rs = Forms![navigation form]![NavigationSubform].Recordset.Clone
Changing from Recordset.Clone to Form.RecordsetClone cured the error (at that line).
Unfortunately you then got error 438 again when attempting to set Bookmark at this line ...
Forms![navigation form]![NavigationSubform].Bookmark = rs.Bookmark
The reason for the error at that point was because [NavigationSubform] is a subform control, and a control does not have a Bookmark property. You need to set the Bookmark on the Form contained within that control.
This code does what I believe you want. I tested it in Access 2010 with a copy of your database.
Dim rs As DAO.Recordset
Dim strLinkValue As String
strLinkValue = Me![Staff ID].Value
With Me.Parent.Form
Set rs = .RecordsetClone
rs.FindFirst "[Staff ID] = '" & strLinkValue & "'"
.Bookmark = rs.Bookmark
End With

Displaying a recordset on a form in Access 2010 using VBA

I'm developing a data retrieval application in Access 2010 in which the user chooses which table, columns, and rows to view by selecting listbox entries. The VBA code generates a SQL statement from these choices and then creates an ADBDB.Recordset object from this.
How can I display the recordset records in Access? None of the grid controls work in Access 2010 and the subform just isn't designed for this purpose. Can someone recommend another strategy?
You could save the SELECT statement as a named query, then open the query as a datasheet. It's not really a form, but somewhat form-like.
Call DatasheetFromSql(strSql)
Public Sub DatasheetFromSql(ByVal pSql As String)
Const cstrQuery As String = "qryDiscardMe"
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strMsg As String
On Error GoTo ErrorHandler
Set db = CurrentDb
db.QueryDefs.Delete cstrQuery
Set qdf = db.CreateQueryDef(cstrQuery, pSql)
DoCmd.OpenQuery cstrQuery, , acReadOnly
ExitHere:
On Error GoTo 0
Set qdf = Nothing
Set db = Nothing
Exit Sub
ErrorHandler:
Select Case Err.Number
Case 3265 ' Item not found in this collection. '
Resume Next
Case Else
strMsg = "Error " & Err.Number & " (" & Err.description _
& ") in procedure DatasheetFromSql"
MsgBox strMsg
GoTo ExitHere
End Select
End Sub
I opened the query read-only. If you want to allow users to edit the data returned by their custom queries, I would not recommend this approach. Instead I would invest the effort in the approach HK1 offered because it can support better control of the user data changes.
With the query opened as a datasheet, you can use Screen.ActiveDatasheet to inspect its properties. At least some of the methods are also available to you. For example you could resize/reposition the datasheet like this:
Screen.ActiveDatasheet.Move Left:=0, Top:=0, Width:=(4 * 1440), Height:=(3 * 1440)
The units are twips (1440 twips / inch), so that would make the width 4 in., height 3 in., and move it to the upper left corner of the Access window.
Here's what I think you'll have to do to get this kind of functionality.
You'll first need to create enough of the correct controls on a form to handle every possible scenario. You'll then need to set the form to be a datasheet form so that it appears as a grid.
Now set the controlsource on your controls to correspond with one of the fields in the recordset. On every control that is not in use needs to have it's ColumnHidden property set to true. You'll also have to change the caption of the associated label to show the appropriate column name for each control that will be visible.
Now, bind that form to your ADO recordset object.
Me.Recordset = rst
'or
Me.Subform1.Form.Recordset = rst
Is this a perfect solution? Most certainly not. Access doesn't have anything that compares to the DataGridView in .Net or even to the Grid controls that are used in VB6. In my opinion, you're really pushing the limits of Access to try to get this sort of functionality. It's like swimming upstream. You'll find that everything you do is going to be fairly difficult and some things just aren't going to be possible.
for an ADP Project where you can't have local MS Access query definitions, you can create a datasheet form with multiple textboxs named txt1, txt2,.... txt30 and labels name lbl1 ... lb30 and this code will set the form.recordsource and set the textbox.controlsource and the label.caption to the appropriate fields from an ADO recordset object. This form will allow you to view your ADO Recordset similar to the Docmd.OpenQuery method.
You must pass the ADO recordset's SQL statement to the form using the OpenArgs property of the form. the code below shows the VBA code to call\open the form (which shows the ADO Recordset like a query) and pass your sql string. The vba code on the form's load event will set all the control properties, resize the columns that have data and hide the columns that do not have a corresponding field from the ado recordset:
'stevekirchner 09/29/2012 Replace Access parameterized query with SQL Server in-line function
'DoCmd.OpenQuery "qry_SearchMaster_CaseTitles", , acReadOnly
strsql = "Select * from dbo.UDF__qry_SearchMaster_CaseTitles ('%" & Me.tbxSearchTerm.Value & "%') "
Call Display_ADO_Recordset_from_Datasheet_Form(strsql, "frm_Display_ADO_Recordset_Result1")
'create a non-form module and put the code for the sub Display_ADO_Recordset_from_Datasheet_Form
'and function fIsLoaded in it (this will allow you make several forms to view ADO recordset and
'call the code from one place\module):
Sub Display_ADO_Recordset_from_Datasheet_Form(sSQL As String, sFormName As String)
On Error GoTo Error_Handler
If fIsLoaded(sFormName) Then
DoCmd.Close acForm, sFormName
End If
DoCmd.OpenForm sFormName, acFormDS, , , acFormReadOnly, , OpenArgs:=sSQL
Exit_Sub:
Exit Sub
Error_Handler:
MsgBox Err.Description & " Error No: " & CStr(Err.Number)
Resume Exit_Sub
End Sub
Function fIsLoaded(ByVal strFormname As String) As Boolean
On Error GoTo Error_Handler
'Returns False if form is not open or True if Open
If SysCmd(acSysCmdGetObjectState, acForm, strFormname) <> 0 Then
If Forms(strFormname).CurrentView <> 0 Then
fIsLoaded = True
End If
End If
Exit_Function:
Exit Function
Error_Handler:
MsgBox Err.Description & " Error No: " & CStr(Err.Number)
fIsLoaded = False
Resume Exit_Function
End Function
'Create a datasheet view form (named frm_Display_ADO_Recordset_Result1) with 30 textboxes and 30
'30 labels named txt1 - txt30 and lbl1 - lbl30 and put this code in the form's module:
Option Compare Database
Private Sub Form_Load()
On Error GoTo Error_Handler
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim rsClone As ADODB.Recordset
Dim strsql As String
Set conn = CurrentProject.Connection
Set rs = New ADODB.Recordset
strsql = Me.OpenArgs
rs.Open strsql, conn, adOpenStatic, adLockOptimistic
Set rsClone = rs.Clone
Call Update_Form_Controls("your text goes here", strsql, rsClone)
Exit_Sub:
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
Exit Sub
Error_Handler:
MsgBox Err.Description & "; Error Number : " & Err.Number, vbOKOnly
Resume Exit_Sub
End Sub
Sub Update_Form_Controls(Header_Label As String, SQL As String, CloneRS As Recordset)
Dim rsCount As Integer
Dim i As Integer
On Error GoTo Error_Handler
Me.Form.Caption = Replace(SQL, "Select * From ", "Display: ")
rsCount = CloneRS.RecordCount
If rsCount <= 0 Then
MsgBox "The Query did not return any data to view", vbOKOnly
DoCmd.Close
Else
Me.Form.SetFocus
Me.RecordSource = SQL
i = 1
Do Until i = 31
Me("lbl" & i).Caption = ""
Me("txt" & i).ControlSource = ""
Me("txt" & i).ColumnHidden = True
i = i + 1
Loop
i = 1
With CloneRS
For Each Field In .Fields
On Error Resume Next
Me("lbl" & i).Caption = .Fields(i - 1).Name
Me("txt" & i).ControlSource = .Fields(i - 1).Name
Me("lbl" & i).Visible = True
Me("txt" & i).ColumnHidden = False
Me("txt" & i).SizeToFit
i = i + 1
'Debug.Print Field.Name
On Error GoTo 0
Next Field
End With
End If
Exit_Sub:
Me.Requery
Exit Sub
Error_Handler:
MsgBox Err.Description & "; Error Number : " & Err.Number, vbOKOnly
Resume Exit_Sub
End Sub
I don't use ADO but simply VBA, in which case above approach is wrong: one doesn't need any means for displaying an existing recordset in a form, but should on the contrary define an adequate recordset within the form !
Instead of creating MyDataBase.OpenRecordset ("SELECT … [SQL query] ;"), just set the form's RecordSource to the very same query definition:
Forms![MyDisplayForm].RecordSource = "SELECT … [SQL query] ;"
Forms![MyDisplayForm].Requery
For me this works perfectly (Windows 7 pro ×64 / MS Office pro ×64)

Get Paragraphs in specific Section of Word Document

I'm having problems finding a specific section in word. It was recommended I try looking through the VB Object Browser in Word for help. I know there are at least 5 heading "sets" (I.E. if you look in the Document Map, I see numbered 1,2,3,4,5...). I don't know how to navigate to that fifth heading, initially I thought it was sections, but when I viewed sections I realized that almost all of it is in one section, but in case anyone is looking for information on how to do sections, the below seems to work, since I already went through the trouble of writing it.
my($document) = $Word->Documents->Open($input) || die("Unable to open document ", Win32::OLE->LastError());
my $section = $document->{Sections}->Item(1); # put section number you're looking for in here
$section_five_paragraphs = $section->{Range}->Paragraphs();
$enumerate = new Win32::OLE::Enum($section_five_paragraphs);
while (defined($paragraph = $enumerate->Next()))
{
print $paragraph->{Range}->{Text} . "\n";
}
So does anyone know how to get to this 5th heading area, or can point me to something that might help?
Tell me if I didn't follow you correctly but you're trying to find the 5th Heading 1 in the a certain section? If that's the case, although Word clearly defines sections (which you note as $document->{Sections}->Item(1)), it does not clearly define Headings in specific or styles in general. For that you'll have to go through all the styles looking for those of interest. The following VBA code (and I apologize for not writing perl) does just that and looks only in a specific section.
Sub FindHeading1()
On Error GoTo MyErrorHandler
Dim currentDocument As Document
Set currentDocument = ActiveDocument
Dim findRange As Range
Set findRange = currentDocument.Sections(2).Range 'which section you want
Dim endRange As Long
endRange = findRange.end
findRange.Find.ClearFormatting
findRange.Find.Style = ActiveDocument.Styles("Heading 1")
Dim headingCountFound As Long
Do While findRange.Find.Execute(FindText:="")
If findRange.End > endRange Then Exit Sub
findRange.Select
headingCountFound = headingCountFound + 1
If headingCountFound = 3 Then 'which occurance you want
MsgBox "Found."
Exit Do
End If
DoEvents
Loop
Exit Sub
MyErrorHandler:
MsgBox "FindHeading1" & vbCrLf & vbCrLf & "Err = " & Err.Number & vbCrLf & "Description: " & Err.Description
End Sub

I need to convert the date from mm/dd/yyyy to dd/mm/yyyy in vbscript

So far I have this:
FormatDateTime(negativeItemsRS("ItemDate"), 0)
Its displaying the date in the format of mm/dd/yyyy. I want to convert that to a dd/mm/yyyy
Please help not sure how to do this.
Thanks,
You have to set the locale id to one that uses the date format that you want. I don't remember which format used where, but either UK (2057) or US (1033) should work.
You haven't specified your environment. In ASP you could use the LCID property in the Language directive or in the Session or Response classes, depending on what scope you want for the setting:
<%#Language="VBScript" LCID="1033"%>
or
Session.LCID = 1033
or
Response.LCID = 1033
To change the date from MM/DD/YYY to DD/MM/YYYY in VB Script very simple steps can be used as given below
Let say "date1" (MM/DD/YY) = 03/06/2014
I want "date2" to be in DD/MM/YY as 06/03/2014
d = Day(date1)
m = Month(date1)
y = Year(date1)
date2 = d & "/" & m & "/" & y
Will give the required result.
What you need is a FormatDate function. I used to do this the hard way with manual concatentation, but I discovered that there are a few .NET libraries that are accessible from COM and thus from ASP Classic. My version leverages the fact that I have a StringBuilder class which is a wrapper around the StringBuilder class in .NET.
'******************************************************************************
Public Function FormatDate( sFormat, dDateValue )
'PURPOSE: To format a date with any arbitrary format
'ARGS:
' sFormat is the defined formats as used by the .NET Framework's System.DateTimeFormatInfo.
' Note that this format is case-sensitive.
'CALLS:
' 1. System.Text.StringBuilder class in the .NET Framework.
'EXAMPLE CALL:
' Dim sFormatedDate
' sFormatedDate = FormatDate( "MM/dd/yy", "1/1/1900 12:00 AM" )
' Or
' sFormatedDate = FormatDate( "MM/dd/yyyy", "1/1/1900 12:00 AM" )
'DESIGN NOTE:
' This function leverages the fact that System.Text.StringBuilder is COMVisible.
' Thus, we can call its AppendFormat function from here.
' You can find more information about the format string parameters allowed at
' http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx
Dim oStringBuilder
Dim sSbFormatString
Dim dDate
If Not IsDate( dDateValue ) Then
FormatDate = vbNullString
Exit Function
End If
On Error Resume Next
dDate = CDate(dDateValue)
If Err.number <> 0 Then
FormatDate = vbNullString
Exit Function
End If
'if an empty format string is passed, then simply return
'the value using the default shortdate format.
If Len(sFormat & vbNullString) = 0 Then
sSbFormatString = "{0:d}"
Else
sSbFormatString = "{0:" & sFormat & "}"
End If
Set oStringBuilder = CreateObject("System.Text.StringBuilder")
Call oStringBuilder.AppendFormat(sSbFormatString, dDate)
FormatDate = oStringBuilder.ToString()
Set oStringBuilder = Nothing
End Function
'**************************************************************************
' Use this class to concatenate strings in a much more
' efficient manner than simply concatenating a string
' (strVariable = strVariable & "your new string")
Class StringBuilder
'PURPOSE: this class is designed to allow for more efficient string
' concatenation.
'DESIGN NOTES:
' Originally, this class built an array and used Join in the ToString
' method. However, I later discovered that the System.Text.StringBuilder
' class in the .NET Framework is COMVisible. That means we can simply use
' it and all of its efficiencies rather than having to deal with
' VBScript and its limitations.
Private oStringBuilder
Private Sub Class_Initialize()
Set oStringBuilder = CreateObject("System.Text.StringBuilder")
End Sub
Private Sub Class_Terminate( )
Set oStringBuilder = Nothing
End Sub
Public Sub InitializeCapacity(ByVal capacity)
On Error Resume Next
Dim iCapacity
iCapacity = CInt(capacity)
If Err.number <> 0 Then Exit Sub
oStringBuilder.Capacity = iCapacity
End Sub
Public Sub Clear()
Call Class_Initialize()
End Sub
Public Sub Append(ByVal strValue)
Call AppendFormat("{0}", strValue)
End Sub
Public Sub AppendFormat(ByVal strFormatString, ByVal strValue)
Call oStringBuilder.AppendFormat(strFormatString, (strValue & vbNullString))
End Sub
'Appends the string with a trailing CrLf
Public Sub AppendLine(ByVal strValue)
Call Append(strValue)
Call Append(vbCrLf)
End Sub
Public Property Get Length()
Length = oStringBuilder.Length
End Property
Public Property Let Length( iLength )
On Error Resume Next
oStringBuilder.Length = CInt(iLength)
End Property
'Concatenate the strings by simply joining your array
'of strings and adding no separator between elements.
Public Function ToString()
ToString = oStringBuilder.ToString()
End Function
End Class
So, with this class you could do something like:
FormatDate("dd/MM/yyyy", RS("DateField"))
Note that the string passed in is case-sensitive.
EDIT I see that at some point I amended my FormatDate function to eliminate the use of my VBScript StringBuilder class and instead just use the .NET class directly. I'll leave the VBScript StringBuilder class in there for reference in case anyone is interested. (I did swap the order of the two however to make the code that appears at the top more applicable to the problem).