Solved

aht_APIGetOpenFileName does not work

Posted on 2014-12-03
23
278 Views
Last Modified: 2014-12-09
Hello,

I've been using the code below, to open file dialogs, for years and now its stopped working. I've done some research and found that is a 64 bit issue so I modified the code.  However the code won't compile and instead generate an compilation error on PtrSafe.

Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" _
   Alias "GetOpenFileNameA" (OFN As OPENFILENAME) As Boolean


' Module     : basFileDialog
' Description:
' Procedures : TestIt()
'              GetOpenFile(Optional varDirectory As Variant, Optional varTitleForDialog As Variant) As Variant
'              ahtCommonFileOpenSave( Optional ByRef Flags As Variant, Optional ByVal InitialDir As Variant, Optional ByVal Filter As Variant, Optional ByVal FilterIndex As Variant, Optional ByVal DefaultExt As Variant, Optional ByVal FileName As Variant, Optional ByVal DialogTitle As Variant, Optional ByVal hwnd As Variant, Optional ByVal OpenFile As Variant) As Variant
'              ahtAddFilterItem(strFilter As String, strDescription As String, Optional varItem As Variant) As String
'              TrimNull(ByVal strItem As String) As String
'              FixPath(ByVal path As String) As String
' Modified   :

'
' --------------------------------------------------
Option Compare Database

Option Explicit

'***************** Code Start **************
' This code was originally written by Ken Getz.
' It is not to be altered or distributed, 'except as part of an application.
' You are free to use it in any application,
' provided the copyright notice is left unchanged.
'
' Code originally courtesy of:
' Microsoft Access 95 How-To
' Ken Getz and Paul Litwin
' Waite Group Press, 1996
' Revised to support multiple files:
' 28 December 2007



Type tagOPENFILENAME
    lStructSize As PTRLong
    hwndOwner As PTRLong
    hInstance As PTRLong
    strFilter As PTRString
    strCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    strFile As String
    nMaxFile As Long
    strFileTitle As String
    nMaxFileTitle As Long
    strInitialDir As String
    strTitle As String
    Flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    strDefExt As String
    lCustData As Long
    lpfnHook As PTRLong
    lpTemplateName As String
End Type

Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" _
   Alias "GetOpenFileNameA" (OFN As OPENFILENAME) As Boolean

 Declare PtrSafe Function GetSaveFileName Lib "comdlg32.dll" _
   Alias "GetSaveFileNameA" (OFN As OPENFILENAME) As Boolean


'Declare Function aht_apiGetOpenFileName Lib "comdlg32.dll" _
'() '    Alias "GetOpenFileNameA" (OFN As tagOPENFILENAME) As Boolean
'
'Declare Function aht_apiGetSaveFileName Lib "comdlg32.dll" _
'() '    Alias "GetSaveFileNameA" (OFN As tagOPENFILENAME) As Boolean
Declare Function CommDlgExtendedError Lib "comdlg32.dll" () As Long

Global Const ahtOFN_READONLY = &H1
Global Const ahtOFN_OVERWRITEPROMPT = &H2
Global Const ahtOFN_HIDEREADONLY = &H4
Global Const ahtOFN_NOCHANGEDIR = &H8
Global Const ahtOFN_SHOWHELP = &H10
' You won't use these.
'Global Const ahtOFN_ENABLEHOOK = &H20
'Global Const ahtOFN_ENABLETEMPLATE = &H40
'Global Const ahtOFN_ENABLETEMPLATEHANDLE = &H80
Global Const ahtOFN_NOVALIDATE = &H100
Global Const ahtOFN_ALLOWMULTISELECT = &H200
Global Const ahtOFN_EXTENSIONDIFFERENT = &H400
Global Const ahtOFN_PATHMUSTEXIST = &H800
Global Const ahtOFN_FILEMUSTEXIST = &H1000
Global Const ahtOFN_CREATEPROMPT = &H2000
Global Const ahtOFN_SHAREAWARE = &H4000
Global Const ahtOFN_NOREADONLYRETURN = &H8000
Global Const ahtOFN_NOTESTFILECREATE = &H10000
Global Const ahtOFN_NONETWORKBUTTON = &H20000
Global Const ahtOFN_NOLONGNAMES = &H40000
' New for Windows 95
Global Const ahtOFN_EXPLORER = &H80000
Global Const ahtOFN_NODEREFERENCELINKS = &H100000
Global Const ahtOFN_LONGNAMES = &H200000

Function TestIt()
    ' Comments:
    ' Params  :
    ' Returns :
    ' Modified:
    
    On Error GoTo PROC_ERR
    
    Dim strFilter As String
    Dim lngFlags As Long
    strFilter = ahtAddFilterItem(strFilter, "Access Files (*.accdb)", _
                    "*.accdb")
    strFilter = ahtAddFilterItem(strFilter, "dBASE Files (*.dbf)", "*.DBF")
    strFilter = ahtAddFilterItem(strFilter, "Text Files (*.txt)", "*.TXT")
    strFilter = ahtAddFilterItem(strFilter, "All Files (*.*)", "*.*")
    
    ' Uncomment this line to try the example
    ' allowing multiple file names:
    ' lngFlags = ahtOFN_ALLOWMULTISELECT Or ahtOFN_EXPLORER
    
    Dim varResult As Variant
    
    varResult = ahtCommonFileOpenSave(InitialDir:="C:\", _
        Filter:=strFilter, FilterIndex:=3, Flags:=lngFlags, _
        DialogTitle:="Hello! Open Me!")
    
    If lngFlags And ahtOFN_ALLOWMULTISELECT Then
        If IsArray(varResult) Then
            Dim intI As Integer
            For intI = 0 To UBound(varResult)
                MsgBox varResult(intI)
            Next intI
        Else
            MsgBox varResult
        End If
    Else
        MsgBox varResult
    End If
    
    ' Since you passed in a variable for lngFlags,
    ' the function places the output flags value in the variable.
    'Debug.Print Hex(lngFlags)
    
PROC_EXIT:
    Exit Function
    
PROC_ERR:
    MsgBox Err.Number & vbTab & Err.Description, vbCritical, "basFileDialog.TestIt"
    Resume PROC_EXIT
    
End Function

Function GetOpenFile(Optional varDirectory As Variant, _
    Optional varTitleForDialog As Variant) As Variant
    ' Comments:
    ' Params  : varDirectory
    '           varTitleForDialog
    ' Returns : Variant
    ' Modified:
    
    ' Here's an example that gets an Access database name.
    
    On Error GoTo PROC_ERR
    
    Dim strFilter As String
    Dim lngFlags As Long
    Dim varFileName As Variant
    
    ' Specify that the chosen file must already exist,
    ' don't change directories when you're done
    ' Also, don't bother displaying
    ' the read-only box. It'll only confuse people.
    lngFlags = ahtOFN_FILEMUSTEXIST Or _
                ahtOFN_HIDEREADONLY Or ahtOFN_NOCHANGEDIR
    If IsMissing(varDirectory) Then
        varDirectory = ""
    End If
    If IsMissing(varTitleForDialog) Then
        varTitleForDialog = ""
    End If
    
    ' Define the filter string and allocate space in the "c"
    ' string Duplicate this line with changes as necessary for
    ' more file templates.
    strFilter = ahtAddFilterItem(strFilter, _
                "Access (*.accdb)", "*.accdb")
    
    ' Now actually call to get the file name.
    varFileName = ahtCommonFileOpenSave( _
                    OpenFile:=True, _
                    InitialDir:=varDirectory, _
                    Filter:=strFilter, _
                    Flags:=lngFlags, _
                    DialogTitle:=varTitleForDialog)
    If Not IsNull(varFileName) Then
        varFileName = TrimNull(varFileName)
    End If
    GetOpenFile = varFileName
    
PROC_EXIT:
    Exit Function
    
PROC_ERR:
    MsgBox Err.Number & vbTab & Err.Description, vbCritical, "basFileDialog.GetOpenFile"
    Resume PROC_EXIT
    
End Function

Function ahtCommonFileOpenSave( _
            Optional ByRef Flags As Variant, _
            Optional ByVal InitialDir As Variant, _
            Optional ByVal Filter As Variant, _
            Optional ByVal FilterIndex As Variant, _
            Optional ByVal DefaultExt As Variant, _
            Optional ByVal FileName As Variant, _
            Optional ByVal DialogTitle As Variant, _
            Optional ByVal hwnd As Variant, _
            Optional ByVal OpenFile As Variant) As Variant
    ' Comments:
    ' Params  : Flags
    '           InitialDir
    '           Filter
    '           FilterIndex
    '           DefaultExt
    '           FileName
    '           DialogTitle
    '           hwnd
    '           OpenFile
    ' Returns : Variant
    ' Modified:
    
    ' This is the entry point you'll use to call the common
    ' file open/save dialog. The parameters are listed
    ' below, and all are optional.
    '
    ' In:
    ' Flags: one or more of the ahtOFN_* constants, OR'd together.
    ' InitialDir: the directory in which to first look
    ' Filter: a set of file filters, set up by calling
    ' AddFilterItem. See examples.
    ' FilterIndex: 1-based integer indicating which filter
    ' set to use, by default (1 if unspecified)
    ' DefaultExt: Extension to use if the user doesn't enter one.
    ' Only useful on file saves.
    ' FileName: Default value for the file name text box.
    ' DialogTitle: Title for the dialog.
    ' hWnd: parent window handle
    ' OpenFile: Boolean(True=Open File/False=Save As)
    ' Out:
    ' Return Value: Either Null or the selected filename
    
    On Error GoTo PROC_ERR
    
    Dim OFN As tagOPENFILENAME
    Dim strFileName As String
    Dim strFileTitle As String
    Dim fResult As Boolean
    
    ' Give the dialog a caption title.
    If IsMissing(InitialDir) Then
        InitialDir = CurDir
    End If
    If IsMissing(Filter) Then
        Filter = ""
    End If
    If IsMissing(FilterIndex) Then
        FilterIndex = 1
    End If
    If IsMissing(Flags) Then
        Flags = 0&
    End If
    If IsMissing(DefaultExt) Then
        DefaultExt = ""
    End If
    If IsMissing(FileName) Then
        FileName = ""
    End If
    If IsMissing(DialogTitle) Then
        DialogTitle = ""
    End If
    If IsMissing(hwnd) Then
        hwnd = Application.hWndAccessApp
    End If
    If IsMissing(OpenFile) Then
        OpenFile = True
    End If
    ' Allocate string space for the returned strings.
    strFileName = Left(FileName & String(256, 0), 256)
    strFileTitle = String(256, 0)
    ' Set up the data structure before you call the function
    With OFN
        .lStructSize = LenB(OFN)
        .hwndOwner = hwnd
        .strFilter = Filter
        .nFilterIndex = FilterIndex
        .strFile = strFileName
        .nMaxFile = Len(strFileName)
        .strFileTitle = strFileTitle
        .nMaxFileTitle = Len(strFileTitle)
        .strTitle = DialogTitle
        .Flags = Flags
        .strDefExt = DefaultExt
        .strInitialDir = InitialDir
        ' Didn't think most people would want to deal with
        ' these options.
        .hInstance = 0
        '.strCustomFilter = ""
        '.nMaxCustFilter = 0
        .lpfnHook = 0
        'New for NT 4.0
        .strCustomFilter = String(255, 0)
        .nMaxCustFilter = 255
    End With
    ' This will pass the desired data structure to the
    ' Windows API, which will in turn it uses to display
    ' the Open/Save As Dialog.
    If OpenFile Then
        fResult = aht_apiGetOpenFileName(OFN)
    Else
        fResult = aht_apiGetSaveFileName(OFN)
    End If
    
    ' The function call filled in the strFileTitle member
    ' of the structure. You'll have to write special code
    ' to retrieve that if you're interested.
    If fResult Then
        ' You might care to check the Flags member of the
        ' structure to get information about the chosen file.
        ' In this example, if you bothered to pass in a
        ' value for Flags, we'll fill it in with the outgoing
        ' Flags value.
        If Not IsMissing(Flags) Then
            Flags = OFN.Flags
        End If
        If Flags And ahtOFN_ALLOWMULTISELECT Then
            ' Return the full array.
            Dim varItems As Variant
            Dim strValue As String
            strValue = OFN.strFile
            ' Get rid of empty items:
            Dim intI As Integer
            For intI = Len(strValue) To 1 Step -1
                If Mid$(strValue, intI, 1) <> Chr$(0) Then
                    Exit For
                End If
            Next intI
            strValue = Mid(strValue, 1, intI)
            
            ' Break the list up at null characters:
            varItems = Split(strValue, Chr(0))
            
            ' Loop through the items in the "array",
            ' and build full file names:
            Dim intNumItems As Integer
            Dim astrResult() As String
            
            intNumItems = UBound(varItems) + 1
            If intNumItems > 1 Then
                ReDim astrResult(0 To intNumItems - 2)
                For intI = 1 To intNumItems - 1
                    astrResult(intI - 1) = FixPath(varItems(0)) & varItems(intI)
                Next intI
                ahtCommonFileOpenSave = astrResult
            Else
                ' If you only select a single item,
                ' Windows just places it in item 0.
                ahtCommonFileOpenSave = varItems(0)
            End If
        Else
            ahtCommonFileOpenSave = TrimNull(OFN.strFile)
        End If
    Else
        ahtCommonFileOpenSave = vbNullString
    End If
    
PROC_EXIT:
    Exit Function
    
PROC_ERR:
    MsgBox Err.Number & vbTab & Err.Description, vbCritical, "basFileDialog.ahtCommonFileOpenSave"
    Resume PROC_EXIT
    
End Function

Function ahtAddFilterItem(strFilter As String, _
    strDescription As String, Optional varItem As Variant) As String
    ' Comments:
    ' Params  : strFilter
    '           strDescription
    '           varItem
    ' Returns : String
    ' Modified:
    
    ' Tack a new chunk onto the file filter.
    ' That is, take the old value, stick onto it the description,
    ' (like "Databases"), a null character, the skeleton
    ' (like "*.mdb;*.mda") and a final null character.
    
    On Error GoTo PROC_ERR
    
    If IsMissing(varItem) Then
        varItem = "*.*"
    End If
    ahtAddFilterItem = strFilter & _
                strDescription & vbNullChar & _
                varItem & vbNullChar
    
PROC_EXIT:
    Exit Function
    
PROC_ERR:
    MsgBox Err.Number & vbTab & Err.Description, vbCritical, "basFileDialog.ahtAddFilterItem"
    Resume PROC_EXIT
    
End Function

Private Function TrimNull(ByVal strItem As String) As String
    ' Comments:
    ' Params  : strItem
    ' Returns : String
    ' Modified:
    
    On Error GoTo PROC_ERR
    
    Dim intPos As Integer
    
    intPos = InStr(strItem, vbNullChar)
    If intPos > 0 Then
        TrimNull = Left(strItem, intPos - 1)
    Else
        TrimNull = strItem
    End If
    
PROC_EXIT:
    Exit Function
    
PROC_ERR:
    MsgBox Err.Number & vbTab & Err.Description, vbCritical, "basFileDialog.TrimNull"
    Resume PROC_EXIT
    
End Function

Private Function FixPath(ByVal path As String) As String
    ' Comments:
    ' Params  : path
    ' Returns : String
    ' Modified:
    
    On Error GoTo PROC_ERR
    
    If Right$(path, 1) <> "\" Then
        FixPath = path & "\"
    Else
        FixPath = path
    End If
    
PROC_EXIT:
    Exit Function
    
PROC_ERR:
    MsgBox Err.Number & vbTab & Err.Description, vbCritical, "basFileDialog.FixPath"
    Resume PROC_EXIT
    
End Function

'************** Code End *****************

Open in new window

0
Comment
Question by:chtullu135
  • 9
  • 9
  • 3
  • +1
23 Comments
 
LVL 18

Expert Comment

by:SimonAdept
Comment Utility
If possible, stop using that API call and use the Application.FileDialog instead.
0
 
LVL 26

Assisted Solution

by:Nick67
Nick67 earned 450 total points
Comment Utility
Do it native in VBA

'Declare a variable as a FileDialog object.
Dim fd As FileDialog
'Create a FileDialog object as a File Picker dialog box.
Set fd = Application.FileDialog(msoFileDialogFilePicker)
'Declare a variable to contain the path
'of each selected item. Even though the path is a String,
'the variable must be a Variant because For Each...Next
'routines only work with Variants and Objects.
Dim vrtSelectedItem As Variant

'Use a With...End With block to reference the FileDialog object.
With fd
    .InitialView = msoFileDialogViewDetails
    .Title = "Open File"
    .InitialFileName = "SomePathYouLike"
    .ButtonName = "Open"
    .AllowMultiSelect = False
    'Use the Show method to display the File Picker dialog box and return the user's action.
    'The user pressed the action button.
    If .Show = True Then
        Shell .SelectedItems(0)
    End If
    MsgBox "Done!"
End With

You are the second Asker with that code that is now busted.
http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/Q_28571284.html#a40471096
MS must have pushed out something to break it.
0
 
LVL 18

Expert Comment

by:SimonAdept
Comment Utility
@Nick: The API doesn't work with 64 bit machines. That's progress for you..
0
 
LVL 26

Expert Comment

by:Nick67
Comment Utility
Looks like there's a .Execute, too
Perhaps the Shell call can be dispensed with
0
 
LVL 26

Expert Comment

by:Nick67
Comment Utility
No, it worked and worked fine as @chtullu135  and the other asker will tell you.
And BOTH had the Ken Getz code in their apps
And BOTH are now broken.
But both are using 64-bit Office

64-bit Windows is fine.
But I see that my Office 2013 machines are whining that an update is available.
Something in the latest Office bits busted that code.

What busted or why, I don't know.
0
 

Author Comment

by:chtullu135
Comment Utility
I may have to use a file dialog control but I'm really trying to avoid it.  The Ken Getz code worked on every older version of access and excel.  Maybe Microsoft wants to make us dependent on their controls
0
 

Author Comment

by:chtullu135
Comment Utility
I've checked out the sample you posted Nick and will give it a shot
0
 

Accepted Solution

by:
chtullu135 earned 0 total points
Comment Utility
It works, I'll have to tweek it so I can select an access database.  I'm using it as part of a relinking procedure for split access databases
0
 
LVL 75

Expert Comment

by:DatabaseMX (Joe Anderson - Access MVP)
Comment Utility
Application.FileDialog should work in all cases.
0
 
LVL 26

Expert Comment

by:Nick67
Comment Utility
I wonder what bits MS pushed this week that broke nearly 20 year old code.
0
 
LVL 75

Expert Comment

by:DatabaseMX (Joe Anderson - Access MVP)
Comment Utility
Nick are you talking about the code you posted above using Application.FileDialog ?
0
Complete Microsoft Windows PC® & Mac Backup

Backup and recovery solutions to protect all your PCs & Mac– on-premises or in remote locations. Acronis backs up entire PC or Mac with patented reliable disk imaging technology and you will be able to restore workstations to a new, dissimilar hardware in minutes.

 
LVL 26

Expert Comment

by:Nick67
Comment Utility
No, the OP has been using Ken Getz's common dialog API code from the A95 era for years.  This week it broke -- and for more than one OP.  64 bit Office was affected.
0
 

Author Comment

by:chtullu135
Comment Utility
It's a pity.  I'm going to miss the old code.  I could use it practically anywhere without concern for references.  Well I guess that's the price of progress.
0
 
LVL 26

Expert Comment

by:Nick67
Comment Utility
The only reference is one you need anyway, The MS Office XX.0 library.  Its the same object MS uses for Select, Open and Save As dialogs in Office itself.
0
 
LVL 75

Assisted Solution

by:DatabaseMX (Joe Anderson - Access MVP)
DatabaseMX (Joe Anderson - Access MVP) earned 50 total points
Comment Utility
You only need that Reference if ... you want to use the text constants.  You can use their numeric equivalents w/o the Reference.
And could use

Type
End Type
to create those same constants also.,
mx
0
 

Author Comment

by:chtullu135
Comment Utility
Hello Nick,

I went ahead and modified the code so that it would use late binding.  However, I am trying to return the file path as a string to the calling procedure.  I've been looking for the path method that would return the path of the selected item , but I can't find one.
Public Function GetDbPath() As String


 Dim fd As Object
 Set fd = CreateObject("Scripting.FileSystemObject")
 'Create a FileDialog object as a File Picker dialog box.
 'Set fd = Application.FileDialog(msoFileDialogFilePicker)
 Set fd = Application.FileDialog(3)
 'Declare a variable to contain the path
 'of each selected item. Even though the path is a String,
 'the variable must be a Variant because For Each...Next
 'routines only work with Variants and Objects.
 Dim vrtSelectedItem As Variant
 Dim strResult As String
 'Use a With...End With block to reference the FileDialog object.
 With fd
     '.InitialView = msoFileDialogViewDetails
     .InitialView = 2
     .Title = "Open File"
     .InitialFileName = "SomePathYouLike"
     .ButtonName = "Open"
     .AllowMultiSelect = False
     'Use the Show method to display the File Picker dialog box and return the user's action.
     'The user pressed the action button.
     If .Show = True Then
         
       'Shell .selectedItems(0)
         .getfilepath (.selectedItems(0))
     End If
     
 End With
 'MsgBox strResult

  
End Function

Open in new window

0
 

Author Comment

by:chtullu135
Comment Utility
Hello Nick
Correction - I tried returning the selected item to a string variable
 With fd
     '.InitialView = msoFileDialogViewDetails
     .InitialView = 2
     .Title = "Open File"
     .InitialFileName = "SomePathYouLike"
     .ButtonName = "Open"
     .AllowMultiSelect = False
     'Use the Show method to display the File Picker dialog box and return the user's action.
     'The user pressed the action button.
     If .Show = True Then
         
       'Shell .selectedItems(0)
         strFilePath = .selectedItems(0)
     End If
     
 End With
0
 
LVL 26

Expert Comment

by:Nick67
Comment Utility
I've been looking for the path method that would return the path of the selected item
Here's a working sample with late binding
---my bad, sorry---
.selectedItems(0)
It seems selected items is an collection whose index starts at one
.selectedItems(1)
filedialog.mdb
0
 

Author Comment

by:chtullu135
Comment Utility
Hello Nick,

Thanks for the help.  Everything is working fine.  Below is the modified code
Public Function GetDbPath() As String

 Dim fd As Object
 Set fd = CreateObject("Scripting.FileSystemObject")
 'Create a FileDialog object as a File Picker dialog box.
 'Set fd = Application.FileDialog(msoFileDialogFilePicker)
 Set fd = Application.FileDialog(3)
 'Declare a variable to contain the path
 'of each selected item. Even though the path is a String,
 'the variable must be a Variant because For Each...Next
 'routines only work with Variants and Objects.
 Dim vrtSelectedItem As Variant
 Dim strFilePath As String
 'Use a With...End With block to reference the FileDialog object.
 With fd
     '.InitialView = msoFileDialogViewDetails
     .InitialView = 2
     .Title = "Open File"
     .InitialFileName = "SomePathYouLike"
     .ButtonName = "Open"
     .AllowMultiSelect = False
     'Use the Show method to display the File Picker dialog box and return the user's action.
     'The user pressed the action button.
     If .Show = True Then
         strFilePath = Nz(.selectedItems(1), "")
     End If
     
 End With
 
 GetDbPath = strFilePath
  
End Function

Open in new window

0
 
LVL 26

Expert Comment

by:Nick67
Comment Utility
Hey,

You understand that these are all configurable by you
     .Title = "Open File"
     .InitialFileName = "SomePathYouLike"
     .ButtonName = "Open"

For fun, you can do stuff like
     .Title = "Open the POS file that I have created for you  BWAAAHAAAHAAA!"
     .InitialFileName = "c:\SomeFolder\SomePlace\"
     .ButtonName = "Click and Weep!"

The file preview option is 4
msoFileDialogViewPreview = 4
You can put a really NSFW image in that folder, for fun -- if your workplace is that type.

The reason I point it out is that you still have
.InitialFileName = "SomePathYouLike"
If .InitialFileName  isn't a valid path, it defaults to My Documents

Much mischief can be accomplished if you have ReturnUserName on the go.  People without humor can be given functionality.  People with humor can be given things that amuse them
0
 

Author Comment

by:chtullu135
Comment Utility
Yes, I already reconfigured file name.
0
 
LVL 26

Expert Comment

by:Nick67
Comment Utility
Good enough!
Sometimes folks don't catch the notations I use for what I think should be obvious 'replace me please' text
0
 

Author Closing Comment

by:chtullu135
Comment Utility
Thanks again everyone.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

QuickBooks® has a great invoice interface that we were happy with for a while but that changed in 2001 through no fault of Intuit®. Our industry's unit names are dictated by RUS: the Rural Utilities Services division of USDA. Contracts contain un…
Describes a method of obtaining an object variable to an already running instance of Microsoft Access so that it can be controlled via automation.
Familiarize people with the process of utilizing SQL Server functions from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Microsoft Ac…
In Microsoft Access, learn how to use Dlookup and other domain aggregate functions and one method of specifying a string value within a string. Specify the first argument, which is the expression to be returned: Specify the second argument, which …

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now