How do i view access database ini file records? - ms-access

I have a vb6 project. It was developed by senior. Now I want to change the existing code. I am new for vb6. The database file like ini format. Actually he worked with access database. I want to create some tables in this database. Please give any idea to open ini file in access database or any idea to open ini file.

Oh my, this is old stuff:
Jose 's VB Tips & Tricks
Using Initialization Files
To paraphrase the great American author Mark Twain, reports of the demise
of .ini files have been greatly exaggerated.
While Microsoft has proclaimed the registry to be the proper storehouse of
initialization information, .ini files still have their uses. Among the
advantages of .ini files are:
The files are easily "human readable" using any simple text editor
such as Notepad.
The API code for working with .ini files is considerably simpler than
the equivalent registry APIs.
Files can be easily opened over a network with nothing more than a
basic redirector installed on either end.
Installation of an .ini file is as simple as copying the file to the
Windows directory.
Windows provides a variety of APIs for working with .ini files, including
the GetProfileXXX and WriteProfileXXX functions dedicated to working with
win.ini and the following functions for reading and writing private
initialization files:
GetPrivateProfileString
Read a string from an .ini file.
GetPrivateProfileInt
Read an integer from an .ini file.
WritePrivateProfileString
Write a string to an .ini file.
WritePrivateProfileInt
Write an integer to an .ini file.
Given, however, that all of the data in .ini files is plain old text,
there 's really no need to separately code the xxxInt versions of these
functions. Converting a string to an Int in VB is simple enough using the
CInt() or Val() function, so only the GetPrivateProfileString and
WritePrivateProfileString functions are needed.
Both of these are simple API calls. There is one exception case when
reading .ini files that return a C string with multiple values separated by
Nulls. To parse that string, I've included the MultiCStringToStringArray
function.
Before continuing, you 'll need to add two Declares to the declarations
section of a module somewhere. As a matter of habit, I alias Win32 APIs
with "w32_" so that I can write a VB wrapper function and give it the name
of the API function.
Here 's the declarations section:
Option Explicit
Private Declare Function w32_GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" ( _
ByVal lpAppName As String, _
ByVal lpKeyName As String, _
ByVal lpDefault As String, _
ByVal lpReturnedString As String, _
ByVal nSize As Long, _
ByVal lpFileName As String) As Long
Private Declare Function w32_WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" ( _
ByVal lpApplicationName As String, _
ByVal lpKeyName As Any, _
ByVal lpString As Any, _
ByVal lpFileName As String) As Long
Here 's the code for GetPrivateProfileString:
Public Function GetPrivateProfileString( _
psAppName As String, _
psKeyName As String, _
Optional pvsDefault As Variant, _
Optional pvsFileName As Variant) As String
'********************
' Purpose: Get a string from a private .ini file
' Parameters:
' (Input)
' psApplicationName - the Application name
' psKeyName - the key (section) name
' pvsDefault - Default value if key not found (optional)
' pvsFileName - the name of the .ini file
' Returns: The requested value
' Notes:
' If no value is provided for pvsDefault, a zero-length string is used
' The file path defaults to the windows directory if not fully qualified
' If pvsFileName is omitted, win.ini is used
' If vbNullString is passed for psKeyName, the entire section is returned in
' the form of a multi-c-string. Use MultiCStringToStringArray to parse it after appending the
' second null terminator that this function strips. Note that the value returned is all the
' key names and DOES NOT include all the values. This can be used to setup multiple calls for
' the values ala the Reg enumeration functions.
'********************
' call params
Dim lpAppName As String
Dim lpKeyName As String
Dim lpDefault As String
Dim lpReturnedString As String
Dim nSize As Long
Dim lpFileName As String
' results
Dim lResult As Long
Dim sResult As String
sResult = ""
' setup API call params
nSize = 256
lpReturnedString = Space$(nSize)
lpAppName = psAppName
lpKeyName = psKeyName
' check for value in file name
If Not IsMissing(pvsFileName) Then
lpFileName = CStr(pvsFileName)
Else
lpFileName = "win.ini"
End If
' check for value in optional pvsDefault
If Not IsMissing(pvsDefault) Then
lpDefault = CStr(pvsDefault)
Else
lpDefault = ""
End If
' call
' setup loop to retry if result string too short
Do
lResult = w32_GetPrivateProfileString( _
lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, lpFileName)
' Note: See docs for GetPrivateProfileString API
' the function returns nSize - 1 if a key name is provided but the buffer is too small
' the function returns nSize - 2 if no key name is provided and the buffer is too small
' we test for those specific cases - this method is a bit of hack, but it works.
' the result is that the buffer must be at least three characters longer than the
' longest string(s)
If (lResult = nSize - 1) Or (lResult = nSize - 2) Then
nSize = nSize * 2
lpReturnedString = Space$(nSize)
Else
sResult = Left$(lpReturnedString, lResult)
Exit Do
End If
Loop
GetPrivateProfileString = sResult
End Function
Here 's WritePrivateProfileString:
Public Function WritePrivateProfileString( _
psApplicationName As String, _
psKeyName As String, _
psValue As String, _
psFileName As String) As Boolean
'********************
' Purpose: Write a string to an ini file
' Parameters: (Input Only)
' psApplicationName - the ini section name
' psKeyName - the ini key name
' psValue - the value to write to the key
' psFileName - the ini file name
' Returns: True if successful
' Notes:
' Path defaults to windows directory if the file name
' is not fully qualified
'********************
Dim lResult As Long
Dim fRV As Boolean
lResult = w32_WritePrivateProfileString( _
psApplicationName, _
psKeyName, _
psValue, _
psFileName)
If lResult <> 0 Then
fRV = True
Else
fRV = False
End If
WritePrivateProfileString = fRV
End Function
And finally, here's MultiCStringToStringArray:
Public Sub MultiCStringToStringArray(psMultiCString As String, psaStrings() As String)
'Created: Joe Garrick 01/06/97 9:28 AM
'********************
' Purpose: Convert a multi-string C string to an array of strings
' Parameters:
' (Input)
' psMultiCString - the multiple C string
' (Output)
' psaStrings - returned array of strings
' Notes:
' The original array should be empty and ReDim-able
'********************
Dim iNullPos As Integer
Dim iPrevPos As Integer
Dim iIdx As Integer
' initialize array, setting first element to a zero-length string
iIdx = 0
ReDim psaStrings(0 To iIdx + 1)
psaStrings(iIdx + 1) = ""
Do
' find null char
iNullPos = InStr(iPrevPos + 1, psMultiCString, vbNullChar)
' double null encountered if next pos is old pos + 1
If iNullPos > iPrevPos + 1 Then
' assing to the string array
psaStrings(iIdx) = Mid$(psMultiCString, (iPrevPos + 1), ((iNullPos - 1) - iPrevPos))
iIdx = iIdx + 1
ReDim Preserve psaStrings(0 To iIdx)
iPrevPos = iNullPos
Else
' double null found, remove last (empty) element and exit
ReDim Preserve psaStrings(0 To iIdx - 1)
Exit Do
End If
Loop
End Sub
that 's all there is to coding .ini files.
Notes
Check the SDK documentation for the specifics of behavior of these
functions.
If you send a zero-length string to the write function, the key is
removed.
If you attempt to write a value for a key that does not exist or a
section that does not exist, the key or section will be created.
Despite Microsoft's portrayal of the registry as the central
repository for configuration information under Win95, win.ini and
system.ini are still used, so exercise caution when working with these
files (in other words, make a backup before you experiment).
GetPrivateProfileString returns the requested data, but
WritePrivateProfileString returns a boolean indicating success or
failure. While GetPrivateProfileString is highly reliable, it could
easily be modified to return a Boolean or some other type of status
code indicating the result.
If you use GetPrivateProfileString to return an entire section,
remember to add an additional null (string & vbNullChar will do it)
before calling MultiCStringToStringArray since that function expects
two nulls to terminate the string. Also, keep in mind that only the
key names are returned, not the values.
Return to Top of Page [Return to top of page]
| Home | Jose's World of Visual Basic | Jose's VB Tips & Tricks |
| © 1997 Joe Garrick | Info Center | [E-mail]jgarrick#citilink.com |

Related

getting linked table path with tabledef.connect

I have been trying to get the path to a linked table. I am looping thru the tables. it works one the first loop but not on the 2nd loop. it returns "".
Ive tried several different ways, calling the table by name or by number. the code originally comes from Neville Turbit. Neville's code calls the table by name, but I could not get that to work.
Public Function GetLinkedDBName(TableName As String)
Dim tblTable As TableDef
Dim strReturn As String
Dim i As Integer
On Error GoTo Error_NoTable ' Handles table not found
'---------------------------------------------------------------
'
i = 0
On Error GoTo Error_GetLinkedDBName ' Normal error handling
For Each tblTable In db.TableDefs
If tblTable.Name = TableName Then
strReturn = tblTable.Connect
strReturn = db.TableDefs(i).Connect
Exit For
End If
i = i + 1
Next tblTable
You don't need a loop:
Public Function GetLinkedDBName(TableName As String) As String
Dim strReturn As String
On Error Resume Next ' Handles table not found
strReturn = CurrentDb.TableDefs(TableName).Connect
GetLinkedDBName = strReturn
End Function
This is my modification from Gustav's.
CurrentDb.TableDefs(TableName).Connect command will returns a string like this:
"MS Access;PWD=p455w0rd;DATABASE=D:\Database\MyDatabase.accdb"
The string above contains 3 information and parted by ";" char.
You need to split this information and iterate through it to get specific one which contain database path.
I am not sure if different version of ms access will return exact elements and with exact order of information in return string. So i compare the first 9 character with "DATABASE=" to get the index of array returns by Split command and get path name from it.
Public Function getLinkedDBName(TableName As String) As String
Dim infos, info, i As Integer 'infos and info declared as Variant
i = -1
On Error Resume Next ' Handles table not found
'split into infos array
infos = Split(CurrentDb.TableDefs(TableName).Connect, ";")
'iterate through infos to get index of array (i)
For Each info In infos
i = i + 1
If StrComp(Left(info, 9), "DATABASE=") = 0 Then Exit For
Next info
'get path name from array value and return the path name
getLinkedDBName = Right(infos(i), Len(infos(i)) - 9)
End Function

Extract InfoPath Attachment with VBA

We are archiving a bunch of InfoPath [IP] documents. The data are going to be stored in MS Access 2010 (with attachments in the file system, storing references to them in the Access DB).
I found one VBA solution to extract the file that the IP form contains, but it doesn't function. (http://www.infopathdev.com/forums/p/10182/36240.aspx)
I have found many .NET solutions, but have had no luck converting them to VBA.
How can I take the file name & file contents contained in an IP Attachment node, and (using Access's VBA) create a real file, stored in the file system?
InfoPath attachments are base64 encoded. The encoding can be "unpacked" with
' The MSXML2.DOMDocument class has methods to
' convert a base64—encoded string to a byte array.
Private Function DecodeBase64(ByVal strData As String) As Byte()
Dim obj_XML As MSXML2.DOMDocument
Dim objNode As MSXML2.IXMLDOMElement
' Getting help from MSXML
Set obj_XML = New MSXML2.DOMDocument
Set objNode = obj_XML.createElement("b64")
objNode.DataType = "bin.base64"
objNode.Text = strData
' Return the value
DecodeBase64 = objNode.nodeTypedValue
Set objNode = Nothing
Set obj_XML = Nothing
End Function
The byte arrays' first 16 bytes are a useless header.
The next 4 bytes are a little-endian unsigned integer, of the actual size of the file. This information is unnecessary, too.
The next 4 bytes are a little-endian unsigned integer, of the number of characters in the FileName. The FileName is in UniCode, so it has 2 bytes / char. Multiply the number of the FileName size by 2, therefore. The name will have nulls at the end that need to be removed.
Finally, the remainder past that point is the file.
I decided to create a helper class to split the byte array of the attachment. My class takes a byte array, and a number. the input array will be split into 2 properties, representing the top and bottom halves. That number entered is 1) the number of bytes for the bottom array, and 2) the index of the first byte of the entered array to put into the top part.
I initially fed it the whole attachment, and added it to the object, splitting it at 23. This put the header and the file-size bytes and the filename size, and put them into the bottom array, and the filename and the file contents, and put it into the top.
I made a reference to those two arrays (to persist them), then fet the bottom array into the object, splitting at 19. I discard the bottom, having the filename size in the top.
After converting that to a Long, I fet the upper part into the object, splitting it at the value of FileNameSize times 2. Thus the filename is in the bottom, and the file is in the top.
Using 2 user-defined types, I line up the 4 bytes of the FileName size into 4 contiguous bytes in one, and treat the other UDT as a single long. Using the LSet statement, I copy the 4 contiguous bytes of the 1st UDT to the 4 contiguous bytes of the 2nd UDT. This converts the bytes to a long.
VBA automatically, implicitly converts byte arrays to strings, if you set a string equal to a byte array of UniCode bytes.
Finally, the upper array is copied to a file, using Put.
The class:
Private pLow() As Byte
Private pHigh() As Byte
Private src() As Byte
Private pt As Long
Public Property Get Low() As Byte(): Low = pLow: End Property
Public Property Get High() As Byte(): High = pHigh: End Property
Private Function outOfBounds() As Boolean
Dim msg As String
' Check the bounds
If pt < 0 Then _
msg = "Division point cannot be less than zero"
If pt > (UBound(src) + 1) Then ' When = UBound + 1, copy whole array into pLo
msg = "‘point’ is greater the the size of the array."
End If
If msg <> "" Then
outOfBounds = True
src = Null
Err.Raise vbObjectError + 6, msg
End If
End Function
' point is the index of the 1st element to be copied into pHi
Public Sub Load(SrcArr() As Byte, point As Long)
src = SrcArr ' grant class-wide access.
pt = point ' grant class-wide access.
If outOfBounds() Then Exit Sub
' Create new arrays and assign to private fields
Dim L() As Byte
Dim H() As Byte
Dim hiUB As Long
hiUB = UBound(src) - point
If point <> 0 Then ' <————<< If ‘point’ is 0, then this is just going to be a copy of
ReDim L(point - 1) ' the whole array into pHi; don’t initialize pLo.
End If
If point <> (UBound(src) + 1) Then ' <————<< If it is the SIZE of the array (UBound+1), then this is
ReDim H(hiUB) ' just going to be a copy of the whole array into pLo, so
End If ' there would be no need to initialize pHi.
' Do the two copies
If point <> 0 Then _
MoveMemory L(0), src(0), point ' ‘point’ is the 0-based 1st element to copy into pHi. So it
' also serves as the 1-based copy SIZE, for copying into pLo.
If point <> (UBound(src) + 1) Then _
MoveMemory H(0), src(point), (hiUB + 1)
pLow = L
pHigh = H
End Sub
The processing:
Public Sub processAttachment(dataIn As String, Optional path As String)
On Error GoTo Er
' After development, remove this:
If IsMissing(path) Or path = "" Then path = "had a default here"
Dim fNum As Integer ' File number, for file communication.
Dim fName As String
Dim fNamSz As Long
Dim b_Tmp() As Byte
Dim btArr() As Byte
btArr = DecodeBase64(dataIn) ' <————<<< dataIn is a base64-encoded string. Convert it to a byte array.
Dim cAS As New clsArraySplitter ' Instantiate the class for getting array sections.
cAS.Load btArr, 24 ' Separate the data at the beginning of btArr (whose size is set), from the
btArr = cAS.High ' rest of the data (whose sizes will be different for each attachment).
' Header (16 bytes, 0-15) + 2, 4-byte long int.s = 16 + 4 + 4 = 24.
' Set the dymaically-sized portion of the data (fName & the file) aside, for now.
cAS.Load cAS.Low, 16 ' Dump Hdr; puts part to be dumped in .Low, 2 longs in .High
' Now .Low has header to be dumped; just ignore it,
' .High has fSize & fNameSize (8 bytes, total).
cAS.Load cAS.High, 4 ' Now .Low has fSize (4 bytes; I don't need this info),
' .High has fNameSize (4 bytes).
fNamSz = ByteArrayToLong(cAS.High) ' Get FileName character count
fNamSz = fNamSz * 2 ' UniCode has 2-bytes per character
' Now, refocus on the array having fname & file.
' Separate into 2 parts, the file name, and the file.
cAS.Load btArr, fNamSz ' Now .Low has the fName,
' .High has the file.
' Get fName, then trim null(s) off the right end.
fName = Trim(cAS.Low) ' VB handles this Byte array to string conversion.
Dim pos As Integer
pos = InStr(fName, Chr$(0)) ' No matter how many, pos points at the 1st one.
If pos > 0 Then _
fName = Left$(fName, pos - 1)
' Open output byte array to a file, then close the file.
' I need to check for the existence of the file, and add '(n)' to the filename if it already exists.
' Since attachments are not stored in the XML by name, InfoPath can store attachments with exactly the same name
' (with or w/o different contents) any # of times. Since I’m saving to the file system, I can’t do that.
fName = UniqueFileName(path, fName)
path = path & fName
fNum = FreeFile
Open path For Binary Access Write As fNum
Put fNum, , cAS.High
Rs: Close fNum ' This ‘Close’ is put here, at the resume point, so that it is sure to be closed
Exit Sub
Er: MsgBox "Error, """ & Err.Description & ","" in ""processAttachment()."""
Resume Rs
End Sub
Hope that all formats right . . .

Opening PDF on specific page number in VBA

I am trying to create a button on my access form that allows for the user to view the corresponding page that goes with the data within the form (In this case, a part number is displayed on the form, and I want the button to open the Part Standard file to show the blueprint/diagram of said part)
I have tried using Adobe's page parameters #page=pagenum at the end of my filepath, but doing this doesn't work.
Here is the code I have (Basic, I know) but I'm trying to figure out where to go here. I have simple condensed down my filepath, for obvious reasons - Note: It's not a URL, but a file path if this matters.
Private Sub Command80_Click()
Dim loc As String 'location of file
'loc = Me.FileLoc
loc = "G:\*\FileName.pdf#page=1"
Debug.Print loc
'Debug.Print Me.FileLoc
'Debug.Print Me.FileName
Application.FollowHyperlink loc
End Sub
Is this possible to do this way? I will continue to read other users posts in hopes to find a solution, and I'll note here if I do find one.
Thanks!
Update
I've found a way to do this, just I have 1 small complication now. My database will be accessed by many users, possibly with different versions of Acrobat, or different locations. Here is my working code:
Private Sub Command2_Click()
pat1 = """C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe"""
pat2 = "/A ""page=20"""
pat3 = """G:\*\FileName.pdf"""
Shell pat1 & " " & pat2 & " " & pat3, vbNormalFocus
End Sub
Now, here is my concern. This code opens AcroRd32.exe from a specific file path, if my users have this stored elsewhere or have a different version, this won't work. Does anyone have a suggestion as how to possibly get around this?
Thanks again! :)
The correct way to do this is probably to look up the location of the acrobat reader executable in the system registry. I find that's generally more trouble than it's worth, especially if I have some control over all of the places my program will be installed (within a single intranet, for example). Usually I end up using this function that I wrote:
'---------------------------------------------------------------------------------------
' Procedure : FirstValidPath
' Author : Mike
' Date : 5/23/2008
' Purpose : Returns the first valid path found in a list of potential paths.
' Usage : Useful for locating files or folders that may be in different locations
' on different users' computers.
' Notes - Directories must be passed with a trailing "\" otherwise the function
' will assume it is looking for a file with no extension.
' - Returns Null if no valid path is found.
' 5/6/11 : Accept Null parameters. If all parameters are Null, Null is returned.
'---------------------------------------------------------------------------------------
'
Function FirstValidPath(ParamArray Paths() As Variant) As Variant
Dim i As Integer
FirstValidPath = Null
If UBound(Paths) - LBound(Paths) >= 0 Then
For i = LBound(Paths) To UBound(Paths)
If Not IsNull(Paths(i)) Then
If Len(Dir(Paths(i))) > 0 Then
FirstValidPath = Paths(i)
Exit For
End If
End If
Next i
End If
End Function
The function takes a parameter array so you can pass it as many or as few paths as necessary:
PathToUse = FirstValidPath("C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe", _
"C:\Program Files\Acrobat\Reader.exe", _
"C:\Program Files (x86)\Acrobat\Reader.exe", _
"C:\Program Files\Acrobat\12\Reader.exe")
pat1 = """" & PathToUse & """"
Registry keys are the better way to go, unlike file locations they have consistency between systems.
Below are three functions, two in support of one, and a macro which tests the functions.
GetARE() (Get Adobe Reader Executable) returns the proper path based on a version search in a pre-defined location passed as the argument. This removes the hassle of typing out many different key locations for each version and provides some amount of coverage should future versions be released and installed on a user's system.
I have installed previous versions of Reader to test whether or not the there is consistency in the InstallPath key location, up until quite outdated versions, there is. In fact, mwolfe02 and I both have our keys in the same location, though I am using version 11 and he, at the time of writing, was using 10. I was only able to test this on a x64 system, but you can easily modify the code below to search for both x64 and x86 keys. I expect a large corporation like Adobe to stick to their conventions, so this will likely work for quite some time without much modification even as new versions of Reader are released.
I wrote this quickly, expect inefficiency and inconsistency in naming conventions.
Truly the best approach to ensure the path is almost-always returned would be to simply run a registry search through VBA in a loop for version numbers using "*/Acrobat Reader/XX.YY/InstallPath/" and then including the executable based on a check for the appropriate candidate in the appropriate directory; however, this isn't exactly a very cost-effective solution. My tests have shown that there is quite a bit of consistency between versions as to where the Install Path can be found, and as to what the executable name may be, so I opted for something more efficient if less lasting.
RegKeyRead() and RegKeyExists() were taken from:
http://vba-corner.livejournal.com/3054.html
I have not modified their code. Take into consideration saying thanks to the author of that post, the code is not complex by any means but it did save me the hassle of writing it myself.
Function RegKeyRead(i_RegKey As String) As String
Dim myWS As Object
On Error Resume Next
'access Windows scripting
Set myWS = CreateObject("WScript.Shell")
'read key from registry
RegKeyRead = myWS.RegRead(i_RegKey)
End Function
Function RegKeyExists(i_RegKey As String) As Boolean
Dim myWS As Object
On Error GoTo ErrorHandler
'access Windows scripting
Set myWS = CreateObject("WScript.Shell")
'try to read the registry key
myWS.RegRead i_RegKey
'key was found
RegKeyExists = True
Exit Function
ErrorHandler:
'key was not found
RegKeyExists = False
End Function
Function GetARE(i_RegKey As String) As String
Dim InPath As String
Dim InKey As String
Dim Ind As Integer
Dim PriVer As String
Dim SubVer As String
Dim Exists As Boolean
Exists = False
PriVer = 1
SubVer = 0
For Ind = 1 To 1000
If SubVer > 9 Then
PriVer = PriVer + 1
SubVer = 0
End If
Exists = RegKeyExists(i_RegKey + "\" + PriVer + "." + SubVer + "\InstallPath\")
SubVer = SubVer + 1
If Exists = True Then
SubVer = SubVer - 1
InKey = i_RegKey + "\" + PriVer + "." + SubVer + "\InstallPath\"
InPath = RegKeyRead(InKey)
GetARE = InPath + "\AcroRd32.exe"
Exit For
End If
Next
End Function
Sub test()
Dim rando As String
rando = GetARIP("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Adobe\Acrobat Reader")
MsgBox (rando)
End Sub
I remember that Acrobat reader used to include some ActiveX PDF reader object available for further use with Microsoft Office. Other companies have developed similar products, some of them (in their basic form) even available for free.
That could be a solution, couldn't it? You'd have then to check that your activeX PDF reader supports direct page access in its methods, and distribute it with your apps, or have it installed on your user's computers. It will avoid you all the overhead related to acrobat readers versions follow-up, specially when newer versions will be available on the market and you'll have to update your client interface.
Just to add to mwolfe02's answer, here is a function that tries to retrieve the executable for the file type given (it also uses the registry commands Levy referenced) :
Function GetShellFileCommand(FileType As String, Optional Command As String)
Const KEY_ROOT As String = "HKEY_CLASSES_ROOT\"
Dim sKey As String, sProgramClass As String
' All File Extensions should start with a "."
If Left(FileType, 1) <> "." Then FileType = "." & FileType
' Check if the File Extension Key exists and Read the default string value
sKey = KEY_ROOT & FileType & "\"
If RegKeyExists(sKey) Then
sProgramClass = RegKeyRead(sKey)
sKey = KEY_ROOT & sProgramClass & "\shell\"
If RegKeyExists(sKey) Then
' If no command was passed, check the "shell" default string value, for a default command
If Command = vbNullString Then Command = RegKeyRead(sKey)
' If no Default command was found, default to "Open"
If Command = vbNullString Then Command = "Open"
' Check for the command
If RegKeyExists(sKey & Command & "\command\") Then GetShellFileCommand = RegKeyRead(sKey & Command & "\command\")
End If
End If
End Function
so,
Debug.Print GetShellFileEx("PDF")
outputs:
"C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe" "%1"
and you just have to replace the "%1" with the file you want to open and add any parameters you need.
Here is code the probably you can use..
Private Sub CommandButton3_Click()
Dim strFile As String
R = 0
If TextBox7 = "CL" Then
R = 2
' Path and filename of PDF file
strFile = "E:\Users\Test\Cupertino Current system.pdf"
ActiveWorkbook.FollowHyperlink strFile
End If
if R = 0 Then
MsgBox "Wrong Code"
ComboBox1 = ""
TextBox1 = Empty
'ComboBox1.SetFocus
End If
End Sub
Just need to the right path.. Hope this can help you

Replace Module Text in MS Access using VBA

How do I do a search and replace of text within a module in Access from another module in access? I could not find this on Google.
FYI, I figured out how to delete a module programatically:
Call DoCmd.DeleteObject(acModule, modBase64)
I assume you mean how to do this programatically (otherwise it's just ctrl-h). Unless this is being done in the context of a VBE Add-In, it is rarely (if ever) a good idea. Self modifying code is often flagged by AV software an although access will let you do it, it's not really robust enough to handle it, and can lead to corruption problems etc. In addition, if you go with self modifying code you are preventing yourself from ever being able to use an MDE or even a project password. In other words, you will never be able to protect your code. It might be better if you let us know what problem you are trying to solve with self modifying code and see if a more reliable solution could be found.
After a lot of searching I found this code:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Function to Search for a String in a Code Module. It will return True if it is found and
'False if it is not. It has an optional parameter (NewString) that will allow you to
'replace the found text with the NewString. If NewString is not included in the call
'to the function, the function will only find the string not replace it.
'
'Created by Joe Kendall 02/07/2003
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function SearchOrReplace(ByVal ModuleName As String, ByVal StringToFind As String, _
Optional ByVal NewString, Optional ByVal FindWholeWord = False, _
Optional ByVal MatchCase = False, Optional ByVal PatternSearch = False) As Boolean
Dim mdl As Module
Dim lSLine As Long
Dim lELine As Long
Dim lSCol As Long
Dim lECol As Long
Dim sLine As String
Dim lLineLen As Long
Dim lBefore As Long
Dim lAfter As Long
Dim sLeft As String
Dim sRight As String
Dim sNewLine As String
Set mdl = Modules(ModuleName)
If mdl.Find(StringToFind, lSLine, lSCol, lELine, lECol, FindWholeWord, _
MatchCase, PatternSearch) = True Then
If IsMissing(NewString) = False Then
' Store text of line containing string.
sLine = mdl.Lines(lSLine, Abs(lELine - lSLine) + 1)
' Determine length of line.
lLineLen = Len(sLine)
' Determine number of characters preceding search text.
lBefore = lSCol - 1
' Determine number of characters following search text.
lAfter = lLineLen - CInt(lECol - 1)
' Store characters to left of search text.
sLeft = Left$(sLine, lBefore)
' Store characters to right of search text.
sRight = Right$(sLine, lAfter)
' Construct string with replacement text.
sNewLine = sLeft & NewString & sRight
' Replace original line.
mdl.ReplaceLine lSLine, sNewLine
End If
SearchOrReplace = True
Else
SearchOrReplace = False
End If
Set mdl = Nothing
End Function
Check out the VBA object browser for the Access library. Under the Module object you can search the Module text as well as make replacements. Here is an simple example:
In Module1
Sub MyFirstSub()
MsgBox "This is a test"
End Sub
In Module2
Sub ChangeTextSub()
Dim i As Integer
With Application.Modules("Module1")
For i = 1 To .CountOfLines
If InStr(.Lines(i, 1), "This is a Test") > 0 Then
.ReplaceLine i, "Msgbox ""It worked!"""
End If
Next i
End With
End Sub
After running ChangeTextSub, MyFirstSub should read
Sub MyFirstSub()
MsgBox "It worked!"
End Sub
It's a pretty simple search but hopefully that can get you going.
additional for the function (looping through all the lines)
Public Function ReplaceWithLine(modulename As String, StringToFind As String, NewString As String)
Dim mdl As Module
Set mdl = Modules(modulename)
For x = 0 To mdl.CountOfLines
Call SearchOrReplace(modulename, StringToFind, NewString)
Next x
Set mdl = Nothing
End Function
Enjoy ^^

Is there a way for MS Access to grab the current Active Directory user?

I'm working on a spec for a piece of software for my company and as part of the auditing system I think it would be neat if there was a way to grab the current Active Directory user.
Hopefully something like:
Dim strUser as String
strUser = ActiveDirectory.User()
MsgBox "Welcome back, " & strUser
Try this article - I have some code at work that will erm, work if this doesn't...
Relevant quote:
Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" _
(ByVal IpBuffer As String, nSize As Long) As Long
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" _
(ByVal lpBuffer As String, nSize As Long) As Long
Function ThisUserName() As String
Dim LngBufLen As Long
Dim strUser As String
strUser = String$(15, " ")
LngBufLen = 15
If GetUserName(strUser, LngBufLen) = 1 Then
ThisUserName = Left(strUser, LngBufLen - 1)
Else
ThisUserName = "Unknown"
End If
End Function
Function ThisComputerID() As String
Dim LngBufLen As Long
Dim strUser As String
strUser = String$(15, " ")
LngBufLen = 15
If GetComputerName(strUser, LngBufLen) = 1 Then
ThisComputerID = Left(strUser, LngBufLen)
Else
ThisComputerID = 0
End If
End Function
Here's my version: it will fetch anything you like:
'gets firstname, lastname, fullname or username
Public Function GetUser(Optional whatpart = "username")
Dim returnthis As String
If whatpart = "username" Then GetUser = Environ("USERNAME"): Exit Function
Set objSysInfo = CreateObject("ADSystemInfo")
Set objUser = GetObject("LDAP://" & objSysInfo.USERNAME)
Select Case whatpart
Case "fullname": returnthis = objUser.FullName
Case "firstname", "givenname": returnthis = objUser.givenName
Case "lastname": returnthis = objUser.LastName
Case Else: returnthis = Environ("USERNAME")
End Select
GetUser = returnthis
End Function
I got the original idea from Spiceworks.
Depending on environment variables to remain valid is a bad idea, since they can easily be changed within a user session.
David made a very good point about risk of using environment variables. I can only add that there may be other problems with environment variables. Just look at this actual code fragment from our 5-year old project:
Public Function CurrentWorkbenchUser() As String
' 2004-01-05, YM: Using Application.CurrentUser for identification of
' current user is very problematic (more specifically, extremely
' cumbersome to set up and administer for all users).
' Therefore, as a quick fix, let's use the OS-level user's
' identity instead (NB: the environment variables used below must work fine
' on Windows NT/2000/2003 but may not work on Windows 98/ME)
' CurrentWorkbenchUser = Application.CurrentUser
'
' 2005-06-13, YM: Environment variables do not work in Windows 2003.
' Use Windows Scripting Host (WSH) Networking object instead.
' CurrentWorkbenchUser = Environ("UserDomain") & "\" & Environ("UserName")
'
' 2007-01-23, YM: Somewhere between 2007-01-09 and 2007-01-20,
' the WshNetwork object stopped working on CONTROLLER3.
' We could not find any easy way to fix that.
' At the same time, it turns out that environment variables
' do work on Windows 2003.
' (Apparently, it was some weird configuration problem back in 2005:
' we had only one Windows 2003 computer at that time and it was
' Will's workstation).
'
' In any case, at the time of this writing,
' returning to environment variables
' appears to be the simplest solution to the problem on CONTROLLER3.
' Dim wshn As New WshNetwork
' CurrentWorkbenchUser = wshn.UserDomain & "\" & wshn.UserName
CurrentWorkbenchUser = Environ("USERDOMAIN") & "\" & Environ("USERNAME")
End Function