ESSEXCLN.XXL file not found - essbase

I am trying to create a macro that connects me to Essbase at the push of a button and am using the syntax found here https://docs.oracle.com/cd/E12825_01/epm.111/esb_client.pdf
I keep getting the error message that Essexcln.xll is not found. Is there any way around this error? I have done a file search on my computer and the file is no where to be found.
This is the full code I am using.
Declare PtrSafe Function EssVConnect Lib "ESSEXCLN.XLL" (ByVal sheetName As Variant, ByVal username As Variant, ByVal password As Variant, ByVal server As Variant, ByVal application As Variant, ByVal database As Variant) As Long
Sub Conn()
X = EssVConnect(Null, "email#email.com", "password", "http:", "h", "hg6")
End Sub

I'm guessing you have Smart View installed, but not the classic Excel add-in, which was the predecessor to Smart View. In order to find that .XLL file, you'll need to install the old add-in. Do note that it is not officially supported anymore. That are equivalent functions in the Smart View plugin that you can use instead. There is at least one alternative to the classic Excel add-in if you are looking for full VBA compatibility: the Dodeca Excel Add-in, although it is not free.

Related

How to "flatten" a PDF via "Microsoft Print To PDF" using Win32 API calls in VBA?

I am trying to have my Excel VBA code read an interactive PDF (i.e. a PDF with dropdowns, calendars...etc.). I normally read PDF files by opening them in Word; however, Word removes all the interactive controls while rendering the file (e.g. a calendar control gets completely removed...along with its value).
I know that I can "flatten" the PDF by opening it in Adobe Acrobat Reader (or any browser) and printing it to a PDF (thus replacing all the controls with their selected values). The question is how do I do this programmatically in VBA. I know there are thousands of questions on S.O. about this topic; but, all of the answers either require installing Adobe Acrobat Pro, using a third-party installed application (e.g. CutePDF), submitting the file to an online API, or most commonly, using SendKeys or Win32 API calls to interact with the "Save As" dialog box that appears. The code I am writing will be distributed to multiple users; so, any additional application installations is out of the question (both Acrobat Pro and other third-party conversion tools). The files contain proprietary data; so, an online API is out as well. As far as SendKeys or SendMessage is concerned...frankly, there's got to be a better way.
I've tried numerous methods including Chrome's headless "print-to-pdf"; but it appears that only accepts HTML files (I even tried embedding the PDF into an HTML file but it still did not work).
The closest I've gotten is by using the below code to send data directly to the "Microsoft Print to PDF" driver (it's based on the process described here). The code successfully creates a PDF file...but it's a zero byte file. It seems that the data read from the input file is not being properly accepted by the "WritePrinter" function (although no error occurs). Although the documentation of the "WritePrinter" function states that the "pBuf" parameter should be a byte array, the person who asked this question was passing a string and getting it to work (understanding that they were not trying to print to a GDI printer). My code still just produces a blank PDF file if I convert the byte array to a string or even just read the contents of the input file using FSO's "ReadAll" method.
It is also worth nothing that the return value of the "WritePrinter" function is "1" and the value of the "pcWritten" output is the correct number of bytes...it's just that the PDF file that is produced has a file size of 0 bytes.
So, can anyone figure out how to get the "WritePrinter" function to accept the data being read from the input file?
By the way, an enormous gold star to anyone who can figure this out because, based on my research, the internet is begging for a way to do this without using Acrobat Pro or having to interact with the "Save As" dialog!
UPDATE#1: I have found a few posts online where users are experiencing this issue of the "Microsoft Print to PDF" driver generating blank files manually (here and here). Apparently the primary culprit is special characters in the input file name. I wanted to make it clear that I do not believe this is the issue I am having, as I can print to PDF perfectly fine manually...just not via the code in this post. (Also, just so it's been said, neither the input file path/name nor output file path/name contains special characters). Also, I don't believe it's an issue with the specific install of the print driver (as suggested in some posts) as my code creates 0 byte files on 3 different computers with 3 different OS builds of Windows (18363.1082, 18363.1139, and 19041.572)
UPDATE#2: In my continued research of this issue I found this post on MSDN's Visual Studio help forums. I understand it's for C# but one of the contributers states:
So you should convert managed byte array into unmanaged array, then invoke the method
He provides C# code that uses the "Marshal.AllocCoTaskMem" and "Marshal.Copy" functions to "Copy the managed byte array into the unmanaged array". I'm not familiar with the terms "managed" or "unmanaged" byte arrays so I will continue to do some research on those.
Does anyone have any experience with the "Marshal.AllocCoTaskMem" and "Marshal.Copy" functions from VBA within Excel (VB6)?
UPDATE#3: It has been brought to my attention that the code I've written will ONLY print XPS files to a PDF. I've converted my original interactive PDF to an XPS manually and confirmed that my code worked perfectly in writing that XPS to a PDF.
This now leaves me back at square one: how do I programmatically read an interactive PDF without utilizing any third-party applications or online converters?
Anyone have any ideas?
Type DOCINFO
lpszDocName As String
lpszOutput As String
lpszDatatype As String
End Type
Private Declare PtrSafe Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, ByVal pDefault As Long) As Long
Private Declare PtrSafe Function StartDocPrinter Lib "winspool.drv" Alias "StartDocPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, pDocInfo As DOCINFO) As Long
Private Declare PtrSafe Function StartPagePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long
Private Declare PtrSafe Function WritePrinter Lib "winspool.drv" (ByVal hPrinter As Long, pBuf As Any, ByVal cdBuf As Long, pcWritten As Long) As Long
Private Declare PtrSafe Function EndPagePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long
Private Declare PtrSafe Function EndDocPrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long
Private Declare PtrSafe Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long
Public Sub Print_File_To_PDF(strInputFile As String, strOutputPDF As String)
Dim udtDocInfo As DOCINFO
Dim lngPrinterCheck As Long, lngFileNumber As Long, lngPrinterHandle As Long, lngPrinterOutput as Long
Dim arrBytes() As Byte
'Get handle of printer
lngPrinterCheck = OpenPrinter("Microsoft Print To PDF", lngPrinterHandle, 0)
If lngPrinterCheck = 0 Then
Exit Sub
End If
'Define document info
With udtDocInfo
.lpszDocName = CreateObject("Scripting.FileSystemObject").GetBaseName(strOutputPDF)
.lpszOutput = strOutputPDF
.lpszDatatype = "RAW"
End With
'Read file into byte array
lngFileNumber = FreeFile
Open strInputFile For Binary Access Read As lngFileNumber
ReDim arrBytes(LOF(lngFileNumber))
Get lngFileNumber, , arrBytes()
Close lngFileNumber
'Print byte array to PDF file
Call StartDocPrinter(lngPrinterHandle, 1, udtDocInfo)
Call StartPagePrinter(lngPrinterHandle)
Call WritePrinter(lngPrinterHandle, arrBytes(1), UBound(arrBytes), lngPrinterOutput)
Call EndPagePrinter(lngPrinterHandle)
Call EndDocPrinter(lngPrinterHandle)
Call ClosePrinter(lngPrinterHandle)
End Sub

Winmove() not working with citrix app

I'm back for more help please.
I'm still on the same project as my question a few weeks ago but stuck on another bit.
I have a multiscreen (win 7) set up and am trying to write an application that will start a number of applications and move/resize them in to the correct positions. I'm doing this as a console app in vb.net.
Following the help I received with my last question I can now start up , move , resize, close all the apps I need bar a couple.
Unfortunately I need to run two applications through Citrix.
One is an Excel sheet.
I can find the windows handle for these windows and select them and or close them but MoveWin() or SetWindowPos() doesn't seem to do anything though the title bar of the window I want to move turns blue so I know it is selecting it..
Any assistance would be greatly appreciated.
A section of the code is pasted below. I'm testing this in excel at the moment and I'll port it across to my console app once working...
Thanks...
Public Declare Function SetWindowPos Lib "user32.dll" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public Const SWP_FRAMECHANGED = &H20 'Fully redraw the window in its new position.
Sub MoveWin()
Dim retval As Long
Dim hwnd As Long
Dim RetWhnd As Long
hwnd = '123456'
retval = SetWindowPos(hwnd, RetWhnd, 0, 0, 600, 400, SWP_FRAMECHANGED) ' Application.hwnd
End Sub
I am not at my home machine, so I cannot confirm this, but I am fairly certain that VB 6 has a tab on the compile dialog (last one perhaps) that has a citrix-related option checkbox. If it's not there, it might be in the project properties.
Just in case this helps someone else. I've contacted the Citrix people and they basically don't know the answer. I at least wanted to know if it was possible. Anyway as far as I can ascertain, the move command doesn't seem to be possible across the Citrix divide. The solution I've come up with is to leave the actual move part of the code in the remotely run app. That is build code in to the apps run through Citrix to look at an ini file on the local machine and receive instructions from it.
This now works great but will only work for apps that either have ability to run a container language or can be wrapped up somehow..

Kernel32 issue with MS Access 2010 on Windows Server 2003 32-bit

Hi I have recently installed MS Access 2010 on my Windows Server 2003 32-bit. Since then one of my VBA scripts isn't running properly. MS Access is quitting unexpectedly giving this error with Kernel32 module.
I have used this line in my VBA code.
Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, lpProcessInformation As _
PROCESS_INFORMATION) As Long
Previously I use to have MS Access 2003 version and I never had any problem. Is there any compatibility issue with MS Access 2010-Windows Server 2003-Kernel32. Please help. Thanks
While I can't offer any specific guidance regarding the kernel32 issue you have encountered, I would make the recommendation that you start eliminating 32-bit Windows API calls from your code. Such calls will prevent your code from compiling under 64-bit versions of Access unless you tweak the declarations to make them "pointer safe" (ref: here), and in many of the more common cases where Win32 API calls were used there are more generic methods available now, like the FileDialog object for manipulating "File Open" and "File Save" dialogs.
In this case I would investigate the .Exec and .Run methods of the WScript.Shell object. There is a description of those methods (and the differences between them) here.

Error when reading registry with Visual Basic 6 running on Win7

I have inherited a VB6 application from a friend of a family member, who wants to have some enhancements done to it.
I haven’t developed in VB for more than 3 years (I’m currently developing in MS Dynamics Ax).
I’ve recently upgraded my hardware and am now running Win7. The last time I worked with the app (about a year and a half ago) was on a WinXP platform, and everything worked fine. Now when I run the app (through code) on Win7, I get an error when trying to read from the registry.
Yes, I am running VB as administrator.
The code to read from the registry is:
Public Function sReadRegistry(ByVal hKeyRoot As Long, _
ByVal sSubKey As String, _
ByVal sValueName As String) As String
Dim r As Long
Dim sData As String * 255
Dim lDataSize As Long
Dim sTempVal As String
Dim readValue As String
lDataSize = 255
'Get the Value Requested
lDataSize = 255
r = VRegReadString(hKeyRoot, sSubKey, sValueName, sData, lDataSize)
If r Then
sTempVal = ""
Else
sTempVal = Left$(sData, lDataSize - 1)
End If
sReadRegistry = sTempVal
End Function
The “VRegReadString “ is declared within a module; and is declared as follows:
Declare Function VRegReadString Lib "VREG" (ByVal hKeyRoot As Long, ByVal sSubKey As String, ByVal sValueName As String, ByVal sData As String, ByRef lDataSize As Long) As Long
It complains about the “VREG” library…
The error I get is: “File not found: VREG”.
Is there a reference or component that I forgot to select? Can somebody please help with a solution?
Thanks in advance.
Seeing that the function declaration is an import from an external library called "VREG", you are probably missing the actual library itself, i.e. VREG.DLL. Unfortunately, this doesn't seem to be a common library, so you'd have to come up with it yourself.
Good news is, though, accessing the registry is not really hard and can be done with just the bare Windows API, especially seeing that VREG.DLL does not really seem to add a good deal of abstraction to the regular API. Take a look at these functions:
Registry Functions
...which you can use to easily re-write registry access, provided you fail to procure the needed DLL from somewhere.

How do I close a currently opened MsgBox using VBA?

Is there any option to close the currently opened MsgBox using any code in VBA access form application?
Check out Randy Birch's response on this thread in microsoft.public.vb.general.discussion
He recommends creating a function in a .bas file called MsgBox. Doing so will cause VB to call your function rather than the built in one.
You'd then create your own MsgBox form and build in a timer to close your form after a set period of time. He provides links showing how to do this.
He also discusses a way to explicitly call the built in MsgBox function in case you need to do this.
Note: I've never done this but I've found that Randy Birch is a knowledgeable resource.
MsgBoxes are not intended to be programmatically closed, that's why it's difficult to do so. If you find yourself in a design where you must force close a MsgBox, you should probably re-evaluate your design.
I may be wrong but MsgBox is a blocking call creating a modal form so I don't think there is an easy way such as an option to do that. Do you have a specific use case for this ?
As MarkJ points out, could this could be a dialog generated by Access (rather than a VBA.MsgBox called in your own code)?
For example, when using table's 'dataview' in the Access UI to add a row you get a message, "You are about to append 1 record..." (or similar). Is this the kind of message you mean? If so, there are indeed ways to suppress them...
I used to have an easy answer to this: use the Windows Scripting Shell object, which has a 'Popup' function - a Message Box, just like the VBA MsgBox() function, with a 'SecondsToWait' parameter that provides exactly the timeout you wanted.
With CreateObject("Scripting.WsShell")
.Popup "Watch me disappear in 5 seconds", 5, Application.Name & ": test", vbInformation + vbOkCancel
End With
If you include a 'Cancel' button, it might still work: the available parameters are vbOkCancel, vbYesNoCancel, and vbRetryCancel.
If you're trying to close a dialog box you didn't initiate with your own msgBox() function call, that's unhelpful: and, as I've hinted above, the 'SecondsToWait' parameter doesn't really work these days - someone in Redmond really does't like the idea of one thread closing another thread's helpful warnings and important interruptions to the user's workflow.
However, you can launch a delayed Message Box 'Close' command using the API Timer() function - not quite 'close the currently opened MsgBox', as this requires advance warning that you intended to open it - but it's the closest thing I have, it fits into a self-contained VBA module, and I posted the code in an answer to a very similar StackOverflow question to yours.
I should warn you that the answer in question is using a sledgehammer to crack a nut, with a side order of lengthy explanation.
Rather than writing an alternative to the Access MsgBox from scratch, you might consider using (or at least studying) Arvin Meyer's Custom MessageBox Creator (downloadable on this page).
Message Boxes are meant to depict some information to the user. Hence programmatically closing is not a good design, unless you are not automating some process.
You can use sendkeys or win APIs.
I have had a similar problem; theoretically you can use the "SendKeys" function (see http://msdn.microsoft.com/en-us/library/8c6yea83%28VS.85%29.aspx). However, the MsgBox blocks the running so you cannot use the command. If you know when it going to pop up, you may run (from the script) external whshell that wait some time and then use the SendKeys. But if you know how to do that, tell me (here). Other similar possibility is to open different thread/process for it that will not be block, but I don't know if it is possible in VBA.
An easy to use Win32 based answer to actually be useful calling it. Using the below code you can easily do a timer-based PopUpBox. I like 1/2 second timer control so 2 = 1 second. Found this answer looking for the answer to this thread. Above answers don't seem to work. I want to use this when I want to show a quick message or quick answer default is normally right can be used for more.
Function Code usually in a Module:
Declare Function MessageBoxTimeout Lib "user32.dll" Alias "MessageBoxTimeoutA" ( _
ByVal hwnd As Long, _
ByVal lpText As String, _
ByVal lpCaption As String, _
ByVal uType As Long, _
ByVal wLanguageID As Long, _
ByVal lngMilliseconds As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Public Function PopUpBox(Optional stMessage As String _
= "Yes or No? leaving this window for 1 min is the same as clicking Yes.", _
Optional stTitle As String = "PopUp Window", _
Optional HalfSecTimer As Long = 120, Optional lgVBmsgType As Long = vbYesNo) As Long
Dim RetVal As Long
HalfSecTimer = HalfSecTimer * 500
RetVal = MessageBoxTimeout(FindWindow(vbNullString, Title), stMessage, stTitle, lgVBmsgType, _
0, HalfSecTimer)
PopUpBox = RetVal
End Function
Call Function Code
Examples: Actual code from my database
PopUpBox "Re-Linking and Closing dB", "Closing dB", 3, vbOKOnly
intAnswer = PopUpBox("Software Lock Down Active?", "Security", 10, vbYesNo)
I know this is an old post, put it seems there is a new a easy way to do this:
Sub MessageBoxTimer()
Dim AckTime As Integer, InfoBox As Object
Set InfoBox = CreateObject("WScript.Shell")
'Set the message box to close after 10 seconds
AckTime = 10
Select Case InfoBox.Popup("Click OK (this window closes automatically after 10 seconds).", _
AckTime, "This is your Message Box", 0)
Case 1, -1
Exit Sub
End Select
End Sub
Sample code provided by: Tom Urtis
https://learn.microsoft.com/en-us/office/vba/excel/concepts/controls-dialogboxes-forms/automatically-dismiss-a-message-box