Object.Namespace path error - excel

I wrote this code to return some properties from file:
Dim strMTitle As String
Dim objMshell As Object
Dim objMfolder As Object
Dim objMFolderItem As Object
Dim strMpath As String
strMpath = "C:\Users\User1\Desktop\Test4\"
Set objMshell = CreateObject("shell.application")
Set objMfolder = objMshell.Namespace(strMpath)
Set objMFolderItem = objMfolder.ParseName("test2.xlsm")
strMTitle = objMfolder.GetDetailsOf(objMFolderItem, 21)
Debug.Print strMTitle
The problem is that it keeps returning run time error 91 - Object variable with block variable not set. Weirdest thing is that when I "Hardcode" objMfolder with path like this:
Set objMfolder = objMshell.Namespace("C:\Users\User1\Desktop\Test4\") the code works perferct.
I use this path in multiple places in my macro so I would really like to "store" it in strMpath and use it like this:
Set objMfolder = objMshell.Namespace(strMpath)
Please help!

The code seems to work with the string variable if you use early-binding and the Shell32.Shell as below. Also, .GetDetailsOf with a column argument of 21 returns nothing, but 0 returns the file name.
Option Explicit
'Set Reference to Microsoft Shell Controls and Automation
Sub dural()
Dim strMTitle As String
Dim objMshell As Shell32.Shell
Dim objMfolder As Folder
Dim objMFolderItem As FolderItem
Dim strMpath As String
strMpath = "C:\Users\Ron\Desktop\"
Set objMshell = New Shell32.Shell
Set objMfolder = objMshell.Namespace(strMpath)
Set objMFolderItem = objMfolder.ParseName("20161104.csv")
strMTitle = objMfolder.GetDetailsOf(objMFolderItem, 0)
Debug.Print strMTitle
End Sub

Related

Run time Error 91 with HTML documents in excel VBA [duplicate]

I have the following code:
Sub AddSources()
Dim pubPage As Page
Dim pubShape As Shape
Dim hprlink As Hyperlink
Dim origAddress() As String
Dim exportFileName As String
exportFileName = "TestResume"
Dim linkSource As String
linkSource = "TestSource2"
Dim hyperLinkText As TextRange
For Each pubPage In ActiveDocument.Pages
For Each pubShape In pubPage.Shapes
If pubShape.Type = pbTextFrame Then
For Each hprlink In pubShape.TextFrame.TextRange.Hyperlinks
If InStr(hprlink.Address, "http://bleaney.ca") > 0 Then
hyperLinkText = hprlink.Range
origAddress = Split(hprlink.Address, "?source=")
hprlink.Address = origAddress(0) + "?source=" + linkSource
hprlink.Range = hyperLinkText
End If
Next hprlink
End If
Next pubShape
Next pubPage
ThisDocument.ExportAsFixedFormat pbFixedFormatTypePDF, "C:\" + exportFileName + ".pdf"
End Sub
I am getting the "Object variable or With block variable not set (Error 91)" error on the line with hyperLinkText = hprlink.Range. When I debug I can see that hprlink.Range does have a value. Any thoughts what I'm doing wrong?
As I wrote in my comment, the solution to your problem is to write the following:
Set hyperLinkText = hprlink.Range
Set is needed because TextRange is a class, so hyperLinkText is an object; as such, if you want to assign it, you need to make it point to the actual object that you need.

How do I pass an Object to VBA Class Get Property Method without receiving an 'Object not Defined' Error?

When passing a Worksheet to a Class Object Method, I receive:
Error 91: Object Variable or With Block variable not set.
The problem is, I do not know where it is I have not set an object.
Dim WS As Worksheet
Set WS = oExport.ExportSheet(oExport.WB)
Dim testint As Integer
Dim oAsset As clsAsset
testint = oAsset.AssetIDCol(WS)
I have checked, and the worksheet object is correctly set in Line 2 of the code. The error occurs when assigning a value to the 'testint' variable. Here is the .AssetIDCol() property from my clsAsset property:
Option Explicit
Private priv_asset_id_col As Integer
Public Static Property Get AssetIDCol(WS As Worksheet) As Integer
If Not priv_asset_id_col = Null Then
AssetIDCol = priv_asset_id_col
Exit Property
End If
Dim rngX As Range
Dim Val As Variant
Dim i As Integer
Set rngX = WS.UsedRange '.Rows(1) '.Find(SearchVal, LookAt:=xlWhole)
For i = 1 To rngX.Columns.Count
If InStr(priv_asset_id_col_name, rngX.Cells(1, i).Value) > 0 Then
AssetIDCol = i
priv_asset_id_col = i
Exit Property
End If
Next i
AssetIDCol = 0
End Property
How do I fix this error? The Get property returns an integer, so I am not sure where I am failing to use Set in creating an instance.
The error appears, because oAsset is declared, but not initialized.
The easiest way to fix it is to write Dim oAsset As New clsAsset instead of Dim oAsset As clsAsset. This way you are referring to a new object upon declaration.
Another way is to set the new object explicitly with a new line, after declaring it:
Dim oAsset As clsAsset
Set oAsset = New clsAsset

Count lines (max) with values

I would like to count the lines that have values. I tried oSheet.Rows.Count but that doesn't work. Any idea about this?
My code is the following:
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
oExcel = CreateObject("Excel.Application")
oBook = oExcel.Workbooks.Add
oSheet = oBook.Worksheets("Sheet")
oSheet.Range("A" & max).Value = "0000111"
oSheet.Range("B1").Value ="Name"
oBook.SaveAs("C:\New folder\excel\" & datenw & ".xlsx")
oExcel.Quit()
As said in the comments, the following code should get you the count of rows that have values based on your Range:
Dim rowCount As Integer = oSheet.UsedRange.Rows.Count()
There is however a slight issue with your code I believe. This probably won't work:
oSheet = oBook.Worksheets("Sheet")
The reason it won't, is because "Sheet" doesn't exist on a new Workbook. "Sheet1" does, so this needs to be changed to:
oSheet = oBook.Worksheets("Sheet1")
'or
oSheet = oBook.Worksheets(1) 'remember Excel collections are one based not zero based
Lastly I would look at the way you are closing Excel as oExcel.Quit() is probably leaving an instance of Excel running. Have a look at this answer which links to Siddharth Rout's bit of code:
Private Sub ReleaseObject(ByVal obj As Object)
Try
Dim intRel As Integer = 0
Do
intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Loop While intRel > 0
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
You also to make sure you release in the right order and release everything. This is usually in backwards order:
ReleaseObject(oSheet)
oBook.Close()
ReleaseObject(oBook)
oExcel.Quit()
ReleaseObject(oExcel)
However with all that said I would look at using the Microsoft.Office.Interop.Excel namespace directly rather than declaring objects:
Imports Microsoft.Office.Interop
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim oExcel As New Excel.Application
Dim oWorkbooks As Excel.Workbooks = oExcel.Workbooks
Dim oWorkbook As Excel.Workbook = oWorkbooks.Add()
Dim oSheets As Excel.Sheets = CType(oWorkbook.Sheets, Excel.Sheets)
Dim oWorksheet As Excel.Worksheet = CType(oSheets(1), Excel.Worksheet)
Dim oARange As Excel.Range = oWorksheet.Range("A" & max.ToString()) 'Not sure what max is but I took the assumption it's an Integer
oARange.Value = "0000111"
Dim oBRange As Excel.Range = oWorksheet.Range("B1")
oBRange.Value = "Name"
Dim oUsedRange As Excel.Range = oWorksheet.UsedRange()
Dim rowCount As Integer = oUsedRange.Rows.Count()
oWorkbook.SaveAs("C:\Test.xlsx")
ReleaseObject(oUsedRange)
ReleaseObject(oBRange)
ReleaseObject(oARange)
ReleaseObject(oWorksheet)
ReleaseObject(oSheets)
oWorkbook.Close()
ReleaseObject(oWorkbook)
ReleaseObject(oWorkbooks)
oExcel.Quit()
ReleaseObject(oExcel)
End Sub
Private Sub ReleaseObject(ByVal obj As Object)
Try
Dim intRel As Integer = 0
Do
intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Loop While intRel > 0
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
End Class
I would also then look at turning Option Strict On:
Restricts implicit data type conversions to only widening conversions, disallows late binding, and disallows implicit typing that results in an Object type.
Define a row variable as Long, then start a loop which will end when it finds a blank value in column A:
Dim lRow as Long = 1
Do until oSheet.Range("A" & lRow).Value=""
' increment the loop variable
lRow+=1
Loop
' display the result in a message block
MsgBox(lRow-1)

How to use OpenOffice Spreadsheet to get an image from an excel file

I have a code that exports image from excel into a picturebox and here it is.
Dim appExcel As Object
Set appExcel = CreateObject("Excel.Application")
appExcel.Visible = False
Dim xlsBook As New excel.Workbook
Dim xlsSheet As New excel.Worksheet
Dim rowlocation As Integer
Dim columnlocation As Integer
Dim celladdress As String
Set xlsBook = appExcel.Workbooks.Open(Text1.Text)
Set xlsSheet = xlsBook.Worksheets("Sheet1")
Dim x As excel.Shapes
For Each x In xlsSheet.Shapes
x.Copy
Picture1.Picture = Clipboard.GetData(vbCFBitmap)
Text2.Text = x.Name
rowlocation = x.TopLeftCell.Row
columnlocation = x.TopLeftCell.Column
celladdress = xlsSheet.Cells(x.BottomRightCell.Row + 1, x.TopLeftCell.Column).Address(RowAbsolute:=False, ColumnAbsolute:=False)
MsgBox ActiveSheet.Range(celladdress)
Next
End If
and unfortunately this code wont work on my friends PC becuase he does not have an Excel installed but he has OpenOffice spreadsheet. I tried to open the Excel in Openoffice then the file opens now my goal is how can i convert the code above in OpenOffice? I mean run the code for OpenOffice files.
This is my code but its not working
Dim objServiceManager As Object
Dim objDesktop As Object
Dim objDocument As Object
Dim objText As Object
Dim objCursor As Object
Dim oDoc As Object
Dim ARG()
Dim oGraph As Object
Dim oView As Object
Dim oDrawPage As Object
Dim oSheet As Object
Dim Image As System_Drawing.Image
Dim oimage As Object
Dim osize As Object
Set objServiceManager = CreateObject("com.sun.star.ServiceManager")
Set objDesktop = objServiceManager.createInstance("com.sun.star.frame.Desktop")
Set oDoc = objDesktop.loadComponentFromURL("file:///C:\Users\paul\Desktop\Testing.ods", "_blank", 0, ARG())
Set oSheet = oDoc.getSheets().getByIndex(0)
Set oGraph = oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape")
Set oView = oDoc.CurrentController
Set oDrawPage = oView.getActiveSheet.DrawPage
For i = 0 To 2
For j = 0 To 9
' Form1.Image1.Picture = Clipboard.GetData
Form1.Image1.Picture = LoadPicture(oDrawPage)
Next
Next
TYSM for future help
This is the latest code in VB6 and it has an error saying vnd.sun.star is missing
Dim objServiceManager As Object
Dim objDesktop As Object
Dim objDocument As Object
Dim objText As Object
Dim objCursor As Object
Dim oDoc As Object
Dim ARG()
Dim oGraph As Object
Dim oView As Object
Dim oDrawPage As Object
Dim oSheet As Object
Dim Image As System_Drawing.Image
Dim oimage As Object
Dim osize As Object
Dim Cell As Object
Dim sGraphicUrl As String
Dim oDisp
Dim oFrame
Dim opos As Object
Set objServiceManager = CreateObject("com.sun.star.ServiceManager")
Set objDesktop = objServiceManager.createInstance("com.sun.star.frame.Desktop")
Set osize = objServiceManager.Bridge_GetStruct("com.sun.star.awt.Size")
Set opos = objServiceManager.Bridge_GetStruct("com.sun.star.awt.Point")
Set oDoc = objDesktop.loadComponentFromURL("file:///C:\Users\paul\Desktop\ACE Express - Fairview_Sample PC of Gondola.ods", "_blank", 0, ARG())
Set oSheet = oDoc.getSheets().getByIndex(0)
Set oimage = oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape")
Set oView = oDoc.CurrentController
Set oDrawPage = oView.getActiveSheet.DrawPage
Set oimage = oDrawPage.getByIndex(0)
Image1.Picture = LoadPicture(oimage.GraphicURL)
Here is the output of the unzip picture
I do not know exactly what your code does, because I normally do not use Microsoft Office. However it looks like this task can be accomplished using OpenOffice Basic. One of the best places to learn OpenOffice Basic is Andrew Pitonyak's Macro Document.
To start with, look at section 5.9.5. Convert all linked images.
EDIT:
To do this in Calc, first I went to Tools -> Macros -> Organize Dialogs and created a dialog named "ImageViewerForm" with an image control named "MyImageControl".
Then I went to Tools -> Macros -> Organize Macros -> OpenOffice Basic and added the following code:
Sub ShowImageViewerDialog
oDoc = ThisComponent
oDlg = CreateUnoDialog(DialogLibraries.Standard.ImageViewerForm)
oControl = oDlg.Model.MyImageControl
oDrawPage = oDoc.getDrawPages().getByIndex(0)
oImage = oDrawPage.getByIndex(0)
oControl.ImageURL = oImage.GraphicURL
oDlg.execute()
End Sub
To run the code, go to Tools -> Macros -> Run Macro. Here is the result:
The "Next Image" button should be fairly straightforward to implement by adding an event handler.
For documentation, see GraphicObjectShape and UnoControlButtonModel. But mostly I just used the MRI tool to figure it out.
EDIT 2:
Regarding the error you posted, the GraphicURL property in this case is a string that references an in-memory object, not a filepath. An example of the string is shown here: https://www.openoffice.org/api/docs/common/ref/com/sun/star/graphic/XGraphicObject.html.
So it is not suitable for passing to LoadPicture, which takes a filename.
Perhaps you can get the actual image data from oImage.Bitmap or oImage.Graphic. Use MRI to see what attributes are available.
For example, it looks like there is a getDIB() method that might work like this:
Form1.Image1.Picture = oImage.Bitmap.getDIB()
One more idea: Instead of using an Office application, you could write code that unzips the file and reads each image in the Pictures subdirectory.
I have never tried it but according to the docs you can control Open Office through COM automation.
Your VB6 code above is controlling Excel through COM automation. You could install Open Office on your machine, and see whether you can automate Calc from VB6 to open a spreadsheet and extract an image. I don't know whether it allows that. Excel COM automation is very powerful and allows you to do almost anything, Open Office may not be as powerful (I don't know).
I would advise thinking carefully about what problem you are trying to solve and whether there's another approach entirely!

Offset Function in VBA

Dim temp_match As Single
Dim mid_value As Single
Dim offset1 As Range
Dim offset2 As Range
Dim off_val1 As Range
Dim off_val2 As Range
temp_match = Application.Match(temp_time, Range("B2:B20"), 1) - 1
Set offset1 = Workbooks("Zero Curve").Worksheets("Sheet1").Range("B2:B20")
Set offset2 = Workbooks("Zero Curve").Worksheets("Sheet1").Range("D1:D20")
off_val1 = Evaluate("Offset(offset1, temp_match, 0,2)")
off_val2 = Evaluate("Offset(offset2, temp_match, 0,2)")
mid_value = Application.Forecast(temp_time, off_val2, off_val1)
This code shows an error:
"Object variable or With block variable not set".
Please help.
You have a few issues there. Frst you have to use Set to assign an object variable. Second you can't refer to a VBA variable in a formula string like that. Third there is no need for Evaluate there:
Set offset1 = Workbooks("Zero Curve").Worksheets("Sheet1").Range("B2:B20")
Set offset2 = Workbooks("Zero Curve").Worksheets("Sheet1").Range("D1:D20")
Set off_val1 = offset1.Offset(temp_match, 0).Resize(2)
Set off_val2 = offset2.Offset(temp_match, 0).Resize(2)

Resources