Error accessing external function select - Excel sheet in powerbuilder - excel

This is the my script.
Im getting error in select method.
Please help.
Thanks in advance
OLEObject xlApp,xls_1,xls_2
integer li_rc
string ls_filepath = "D:\backup\"
xlApp = Create OLEObject
li_rc = xlApp.ConnectToNewObject( "Excel.Application" )
if li_rc < 0 then
MessageBox("Connect to Excel Failed !",string(li_rc))
Return -1
end if
xlApp.Application.Workbooks.Open(ls_filepath+'\test1.xls')
xlApp.Application.Workbooks.Open(ls_filepath+'\test2.xls')
xls_1 = xlApp.Application.Workbooks[1].Worksheets[1]
xls_2 = xlApp.Application.Workbooks[2].Worksheets[1]
xls_2.activate()
xls_1 .activate()
xls_2.rows("1:8").copy()
xls_1 .Rows("1:8").Select()
xls_1 .paste()
xlApp.Application.workbooks[1].SaveAs(ls_filepath+"\test3.xls")
xlApp.Application.WorkBooks.close()
xlApp.Application.WorkBooks.Application.quit()
destroy xlApp
destroy xls_1
destroy xls_2
Return 1

Welcome to the wonderful world of dynamic objects (weak typing)
These kinds of things require more conscientious development techniques particularly checking the type of object, property, function or whatever your dot nation has navigated you in the neighborhood of.
But some OLE objects are weak on functions to interrogate the entire object model of a dynamic object forcing you to rely heavily on Microsoft OLE documentation which is boring and often version specific. I think your issue would be easier seen by a VBA and/or Visual Basic Scripting or Excel OLE expert.
But in the name of a PowerBuilder solution. It sometimes helps to wrap operations on dynamic objects in TRY..CATCH..FINALLY clause and then add your own code to handle the various OLE Exceptions and prevent PB from crashing each time your dot nation doesn't match what was expected.

Related

Trying to create an Entity Relationship Database from Excel using Visio Standard

I'm trying to use my company's software, Visio Standard, to create an entity relationship database using Excel. Usually the team has been creating this manually due to not having access to the Professional versions. With a mulitude of entities, the process is extremely tedious doing this one by one. I am trying to import from Excel to Visio without that pro version.
Theoretically the excel template would have Entity Name, Entity Structure (P'ship, Corp, DRE, Individual, ect.) and whatever else information needed to automatically populate into excel.
I have a background in VBA so that could be utilized, I just keep running into roadblocks due to the lack of tabs that the standard version has, including the main Data tab for import.
Is there any way I can import my data from Excel into Visio then run a code to convert it into shapes? What about my own custom template?
We make entity relationship diagrams often so one template would not work. We have a standard shapes & stencils that is used across the board, but the ERD is never the same. I thought I needed a template but I realized that I can't convert a personal template to a wizard or import an excel to the template that the template becomes quite useless.
#Surrogate My idea is that I want to pull the data from a template in excel to automatically create the ERD (or close to it) to save a large sum of time creating those entities through the shapes one by one. I think the template in Excel being so basic, with header columns for the Name of the Entity, Shape to use, hierarchy ladder; VBA does come into play pretty easily, just unsure how to mess around with that since I can't import excel into Visio through the standard version
#y4cine I am stuck because I cannot import data from excel in the standard version.
#TimWilliams I'm not capable of poaching to paying for the pro version, so regardless of the "fun" I would like to see if I could work around the pro version to do what the ERD/wizard can do, even if it requires a large VBA macro.
because I cannot import data from excel in the standard version
This example uses early binding.
In VBA you need to set a reference to the Excel Library.
It sets prop values in already existing shapes. The link being the shape ID.
If you rather need to draw new shapes, I' recommend using a master.
something like:
dim oMaster as master
dim oStencil as document
set oStencil = Application.Documents("myStencil")
set oMaster = oStencil.Masters("myMaster")
then inside the loop:
define some coordinates for x and y
set shp = activepage.drop(oMaster,x,y)
The function:
Public Function excelImport(filename As String) As Boolean
Dim xlsWorkbook As Excel.Workbook
Dim xlsSheet As Excel.Worksheet
Dim shp As Visio.Shape
Dim num_rows As Integer
Dim row As Integer
Dim shpID As String
Set xlsWorkbook = Excel.Workbooks.Open(filename)
Set xlsSheet = xlsWorkbook.Worksheets(1)
num_rows = xlsSheet.Range("A65000").End(xlUp).row
For row = 2 To num_rows
shpID = xlsSheet.Range("P" & row).FormulaR1C1
If Not shpID = "" Then
Set shp = ActivePage.Shapes.ItemFromID(CLng(shpID))
shp.Cells("prop.SoAndSo").Formula = Chr(34) & xlsSheet.Range("A" & row).FormulaR1C1 & Chr(34)
End If
Next row
xlsSheet.Application.Quit
Set xlsSheet = Nothing
Set xlsWorkbook = Nothing
excelImport = True
End Function

What about "Application" as default object in Excel VBA?

I have just written this easy macro in Excel VBA for merging a group of selected cells:
Sub Macro_Merge()
Dim Temp As String
Dim S As Variant
Temp = ""
For Each S In Selection
If Temp = "" Then
Temp = CStr(S.Value)
Else:
Temp = Temp + "," + CStr(S.Value)
End If
Next
Selection.Merge
Selection.Value = Temp
Selection.VerticalAlignment = xlTop
End Sub
This works fine, but I always see that annoying dialog box, warning me about loosing data while merging (which is exactly what I'm trying to avoid in my macro).
I can get rid of that dialog box, configuration the Application's DisplayAlerts property:
Application.DisplayAlerts = False
Selection.Merge
Selection.Value = Temp
Application.DisplayAlerts = True
This is working fine.
So, as Application is the default object, I tried to clean up my code, as follows:
DisplayAlerts = False
Selection.Merge
Selection.Value = Temp
DisplayAlerts = True
As you see, I simply omit mentioning the Application object. This is something which is allowed and I've done in the past. (If not in VBA, then Delphi, maybe?)
... but to my surprise, the dialog box appears again (although pressing F1 brings me to the official "Application.DisplayAlerts" documentation).
This leaves me with a simple question:
If a simple DisplayAlerts = ... does not equal Application.DisplayAlerts = ... anymore, what does it mean and how can I use it?
For your information, I'm working with Excel-365.
DisplayAlerts is an undeclared variable.
Certain Application properties and methods can (effectively) have the Application omitted:
ActiveCell, ActiveSheet, ActiveWorkbook, ActiveWindow, Addins, Charts, Selection, etc.
Calculate, Evaluate, Intersect, Run, Union, etc.
(but see this answer why/how this works):
A boolean property such as DisplayAlerts (EnableEvents, ScreenUpdating, etc) doesn't fall into the above category.
A golden rule in order not to fall into such a trap is the usage of Option Explicit while writing macros.
Just to add some information to the answer of #BigBen. If you write something like Workbooks or ActiveSheet in your code, VBA is not looking into the Application-object - it is looking into a (rather well hidden) object named Global.
The global object is exposing some (but not all) properties and methods of the Application-object, so ActiveSheet is referring to Application.ActiveSheet - but not because the Application has a member with this name but because the Global object defines that ActiveSheet means Application.ActiveSheet. In fact even the Application-object is accessed via the Global object.
There is hardly any information about this Global object or its concept. I found a page from Microsoft describing the Global object of MS Word, but the only explanation there is "Contains top-level properties and methods that don't need to be preceded by the Application property.". For Excel, I found this page on O'Reilly.
From time to time you get strange error messages like "Excel VBA Method 'Range' of object'_global' failed" - this is a pointer to the Global object. I would be glad to learn more about the concepts and mechanics of this object, but I am afraid that there are only very few people around that know more (except of course Mathieu Guindon AKA Mr. Rubberduck...). In daily life, we take it for granted that things like ActiveSheet simply works.

Store Jscript values in Excel

I'm trying to transfer the values stored in a JScript matrix to Excel. The problem is how I should initialize the current Excel Workbook that is opened.
For previous works, in python the code is:
import clr
clr.AddReference("Microsoft.Office.Interop.Excel")
import Microsoft.Office.Interop.Excel as Excel
from System.Runtime.InteropServices import Marshal
ex = Marshal.GetActiveObject("Excel.Application")
ex.Visible = True
wb = ex.ActiveWorkbook
ws_data = wb.Worksheets('name')
So my intention is "translate" this code into Jscript to set the values of my matrix in Excel
There is no "global" conversion of this code into JavaScript. Only Internet Explorer supports something called "Active X objects". In other browsers direct communication between JavaScript and Excel is not possible (at least not "out of the box").
In Internet Explorer you can use the following code:
var ExcelApp = new ActiveXObject("Excel.Application");
See more i.e. here ActiveXObject Object (JavaScript)

Sending commands across VBA

I am writing a script in VBA that creates a drawing in CorelDraw. I am having trouble centering the text. Here is the code that works properly in CorelDraw's Macro editor:
Dim s2 As Object
Dim Txt As Object
Dim test As String
Dim returntest As String
returntest = "Test~Test1234~Test56~Test789"
test = Replace(returntest, "~", Chr(13))
Set s2 = CorelApp.ActiveLayer.CreateArtisticText(-7.75, (1 - 0.5) / 2, test)
Set Txt = s2.Text
Txt.Story.Font = "Swis721 BT"
Txt.Story.Size = 20
Txt.Story.LineSpacing = 75
Txt.Story.Alignment = cdrCenterAlignment
s2.Fill.UniformColor.CMYKAssign 0, 0, 0, 100
s2.Outline.SetNoOutline
s2.CenterX = s1.CenterX
s2.CenterY = s1.CenterY
s1 is simply a rectangle that is already defined. The problem is with "cdrCenterAlignment". VBA does not recognize it as a valid argument because it is referencing something that exists only within CorelDraw. I get "cdrCenterAlignment variable not defined" or "type mismatch" if I call it a string. How, if even possible, can I send this command/argument to CorelDraw while still working in Excel?
I ran into similar problems sending the same drawing to AutoCAD but was able to work around it by sending things to the Command line.
In your VBA code you can define it yourself:
Const cdrCenterAlignment = 3
https://community.coreldraw.com/sdk/api/draw/19/e/cdrAlignment
Reference the CorelDRAW library (Tools > References) and the constants will be defined, and you can use actual CorelDRAW types and API and enjoy IntelliSense and auto-complete, instead of working against the Object interface and constantly referring to documentation for what members are available on what objects - and dealing with run-time error 438 whenever you make a typo, because late-bound code will happily compile and only be resolved at run-time.
Adding a reference to the CorelDRAW type library will allow you to write early-bound code that resolves at compile-time, exactly like the function calls you're making against the VBA or Excel type libraries, which are referenced by default in an Excel VBA project.

MS Access VBA: Reference Excel Application Object created in separate Module

This seems like it should be an easy one but I'm stuck.
I'm running a VBA script in Access that creates a 40+ page report in Excel.
I am creating an Excel Application Object using Early Binding:
Public obj_xl As New Excel.Application
Here is an example of how I am referencing the object:
With obj_xl
.Workbooks.Add
.Visible = True
.Sheets.Add
.blahblahblah
End With
The problem is that the procedure has become too large and I need to break the code up into separate modules.
If I try to reference the Excel Application Object from a different module than it was created in, it throws an error ("Ambiguous Name").
I'm sure I could do something with Win API but that seems like it would be overkill.
Any thoughts? Thanks
this is the type of situation that can cause the error "Ambiguous Name"
Function Split(s As String)
MsgBox s
End Function
Function Split(s As String)
MsgBox s
End Function
I know the example is trivial, but what you are looking for is a function , an object and/or a form control with the same names.
If you convert your declaration to Global, you can reference it in all your modules. For example, in one module, put this at the top:
Global obj_xl As Excel.Application
Then in an another module,
Sub xx()
Set obj_xl = New Excel.Application
Debug.Print obj_xl.Name
End Sub

Resources