Access current ID field to Excel cell - excel

Project Management
Project Details
This is a standard Project Management database, when ID number is pressed it goes to Project Details - pic2.
After that I inserted 2 buttons one for creating a folder and Excel button that opens a specific template.
Button one does this:
Private Sub Command85_Click()
Const strParent = "F:\2. Prodaja\"
Dim projectID As String
Dim strFolder As String
Dim fso As Object
' Get ID from control
projectID = Me.ID
' Full path
strFolder = strParent & projectID
' Create FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")
' Check whether folder exists
If fso.FolderExists(strFolder) = False Then
' If not, create it
fso.CreateFolder strFolder
End If
' Open it
Shell "explorer.exe " & strFolder, vbNormalFocus
End Sub
And the Excel button:
Function OpenExcelFromAccess()
Dim MyXL As Object
Set MyXL = CreateObject("Excel.Application")
With MyXL
.Application.Visible = True
.Workbooks.Open "F:\0. Main\01.Templates\ponuda.xltm"
.Worksheets("Kupci").ListObjects("Employees__4").Refresh
Dim EmpID As Integer
EmpID = ID_Employees
.Worksheets("GlavnaTabela").Cells(3, 25).Value = EmpID
End With
End Function
The idea was to copy the ID_Employee number and paste it to cell Y3, but it doesn't give me the current number of ID_Employees, it gives me 0. First button works and creates folders based on ID. My question is how to get ID_employees from Access Form into Excel cell Y3?
I changed function to Sub and done these changes:
Private Sub Command166_Click()
Dim EmpID As Integer
If IsNull(ID_Employees) Then EmpID = 0 Else EmpID = ID_Employees
Set MyXL = CreateObject("Excel.Application")
With MyXL
.Application.Visible = True
.Workbooks.Open "F:\0. Main\01.Templates\ponuda.xltm"
.Worksheets("Kupci").ListObjects("Employees__4").Refresh
.Worksheets("GlavnaTabela").Cells(3, 25).Value = EmpID
End With
End Sub

Related

Saving and retrieving attachments to a shared Access db, attachment not found for other users

I have an Excel macro that CRUDs work orders to which the user also attaches an image. Everything gets saved to an Access db on a SharePoint folder.
For example, a work order for department A gets created, and to the record we attach a picture to an attachment field in an Access table. Department A receives the work order through the Access database which has been shared through SharePoint.
All users use the same workbook, macros, code, etc.
After a record has been updated with an image, it is displayed with the following:
Dim ws As DAO.Workspace
Dim db As DAO.Database
Dim rs As DAO.Recordset, rsP As Variant, strFile As String
Dim rsStat As DAO.Recordset
Set ws = DBEngine.Workspaces(0)
Set db = ws.OpenDatabase(db_path.Value, False, False, "MS Access;PWD=" & p.Value)
Set rsStat = db.OpenRecordset("SELECT STATUS FROM womhst WHERE wo_no = " & wo_no)
If rsStat.Fields(0).Value = "Closed" Then
btnAddPic.Enabled = False
Else
If Not user_role.Value = 4 Then
btnAddPic.Enabled = False
Else
btnAddPic.Enabled = True
End If
End If
Set rs = db.OpenRecordset("SELECT vio_image FROM womhst WHERE wo_no = " & wo_no)
Set rsP = rs.Fields("vio_image").Value
If rsP.RecordCount = 1 Then iAtt.Picture = LoadPicture(rsP.Fields(2).Value)
If I run this from my machine, the image is displayed in the Image control.
However, when I run the macro from another user's machine, connecting to the Access db shared through a SharePoint folder, I get a "File not found" error when I try to display the image.
I know the following:
Access has updated in the second user's machine. If I open the encrypted db in that user's machine, I can see that the field has all images as it should.
There are other fields on the table, which the macro is reading as well. All of these read fine. If I make an update to the table in one machine, the changes are reflected, and the macro reads them (only with the files in the attachment field there is a problem)
Access is saving the images to a cache for each machine
After I try to view the image from the second user's machine (and get the error), I go back to my machine. At this point, I also start getting the "File not found" error.
I believe this has something to do with the cache path.
The code for updating images to Access:
Dim db As DAO.Database
Dim ws As DAO.Workspace
Dim rst As DAO.Recordset
Dim attachFld As DAO.Recordset
Set ws = DBEngine.Workspaces(0)
Set db = ws.OpenDatabase(db_path.Value, False, False, "MS Access;PWD=" & p.Value)
Set rst = db.OpenRecordset("SELECT * FROM womhst WHERE wo_no = " & wo_no & ";", dbOpenDynaset)
rst.FindFirst "wo_no = " & wo_no
If Not rst.NoMatch Then
rst.Edit
Set attachFld = rst.Fields("vio_image").Value
'If record alrady has an image, delete such that there always only one file saved
If attachFld.RecordCount <> 0 Then
attachFld.Delete
End If
attachFld.AddNew
'user can get the file with the file dialog
Dim objFSO As New FileSystemObject
Dim fileSelected As String
Dim myFile As Object
Set myFile = Application.FileDialog(msoFileDialogOpen)
With myFile
.Title = "Choose File"
.AllowMultiSelect = False
If .Show <> -1 Then
Exit Sub
End If
fileSelected = .SelectedItems(1)
End With
attachFld.Fields("FileData").LoadFromFile fileSelected
attachFld.Update
rst.Update
End If
rst.Close
db.Close
ws.Close
I have found a workaround:
As I attempt to open a photo from the Access database, I save it to a temp folder. After the user views the photo, VBA deletes the temp directory:
Option Explicit
Dim imgDir As String
Private Sub btnExit_Click()
DeleteTemp
Unload Me
End Sub
Private Sub UserForm_Initialize()
LoadImage
End Sub
Private Sub LoadImage()
Dim db As DAO.Database
Dim ws As DAO.Workspace
Dim rst As DAO.Recordset
Dim attachFld As DAO.Recordset
Set ws = DBEngine.Workspaces(0)
Set db = ws.OpenDatabase(db_path.Value, False, False, "MS Access;PWD=" & p.Value)
Set rst = db.OpenRecordset("SELECT * FROM womhst WHERE wo_no = " & wo_no & ";", dbOpenDynaset)
Set attachFld = rst.Fields("vio_image").Value
Dim wd As String
wd = ThisWorkbook.path
imgDir = wd & "\temp3"
MkDir imgDir
attachFld.Fields("FileData").SaveToFile imgDir
iAtt.Picture = LoadPicture(imgDir & "\" & attachFld.Fields(2))
End Sub
Private Sub DeleteTemp()
Dim FSO As New FileSystemObject
Set FSO = CreateObject("Scripting.FileSystemObject")
FSO.DeleteFolder imgDir, False
End Sub

Excel VBA Collect Data from other Excel Files and paste them into Masterfile

I'm a C# Programmer and new into Excel VBA and here I am on my limit.
I don't get the gist how to copy and paste data from different files into one Masterfile..
I want to collect all data from Excel Files in a userdefined folder. These data were always stored in excel files.
And always starts at the D column until last column from the 6th row to last row.
So I want first to get the Parent directory in which I get all the Files in this Parentfolder.
After that I start the CollectSubdataProcedure.
So my approach would be copy the range from each subfile and paste them into the 6th row and last column of my masterfile
Private Sub CollectData()
Dim MasterWorkbook As Workbook
Set MasterWorkbook = Workbooks("Masterfile.xlsm")
Dim Folderpath As String
'Get Folder which contains all Data
Folderpath = UserGetFolder & "\"
Dim obj As Object
Dim ParentFolder As Object
Dim Files As Object
Set obj = CreateObject("Scripting.FileSystemObject")
Set ParentFolder = obj.GetFolder(Folderpath)
Set Files = ParentFolder.Files
Application.ScreenUpdating = False
'Loop through all folder now
Dim subfile As Object
For Each subfile In ParentFolder.Files
'Start Data Collection
Call CollectSubdata(subfile)
Next subfile
End Sub
Here my Sub Procedure
Private Sub CollectSubdata(ByRef subfile As Object)
' Do Data collection here
Dim subwb As Workbook
Dim LastColumn As Double
Dim LastRow As Double
Dim LastMasterCol As Double
LastMasterCol = MasterWorkbook.Sheets(1).Cells(6, Columns.Count).End(xlToLeft).Column
Set subwb = Workbooks.Open(subfile)
LastColumn = subwb.Sheets(1).Cells(1, Columns.Count).End(xlToLeft).Column
LastRow = subwb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row
'Copy all necessary entries
subwb.Sheets(1).Range(Cells(6, 4), Cells(LastRow, LastColumn)).Copy
'Paste into Masterfile
MasterWorkbook.Sheets(1).Cells(6, LastMasterCol).PasteSpecial Paste:=xlPasteAll
subwb.Close
End Sub
And Here my Userdefined Folder
Function UserGetFolder() As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
UserGetFolder = sItem
Set fldr = Nothing
End Function
I don't get the gist of VBA uses these objects and methods..
A variable only exists in the context in which it is defined. In your case the pointer masterworkbook is defined within the routine CollectData so it only exists within that routine. In order to get it into CollectSubData you either need to pass a reference to it as an argument to the subroutine, or define the variable at module level so that it exists for all routines within that module. The former is better practice, so you should define your CollectSubData as
Private Sub CollectSubdata(ByRef subfile As Object, ByRef MasterWorkbook As Workbook)
and call it as
'Start Data Collection
CollectSubdata(subfile,MasterWorkbook)
Note that Call is not needed in this context (although it's not wrong per se)

Excel VBA - create column names using MS Project headers

I'm in the middle of writing a script that populates an excel spreadsheet with data from an MS Project file. I would like the script to recognize the title name of the MS Project columns as I have a number of custom columns with different names (custom number fields are populated with different names)
The code below was my attempt, but i'm getting an error when it comes to writing the value of the task column title to the sheet, am I doing something wrong here?
Sub PopulateSheet()
Dim Proj As MSProject.Application
Dim NewProj As MSProject.Project
Dim t As MSProject.Task
Dim xl as workbook
Dim s as worksheet
Dim Newsheet as worksheet
Set Xl = ThisWorkbook
BookNam = Xl.Name
Set Newsheet = Xl.Worksheets.Add
'Code to find and open project files
Set Proj = New MSProject.Application
MsgBox ("Please Select MS Project File for Quality Checking")
'Select Project File
FileOpenType = Application.GetOpenFilename( _
FileFilter:="MS Project Files (*.mpp), *.mpp", _
Title:="Select MS Project file", _
MultiSelect:=False)
'Detect if File is selected, if not then stop code
If FileOpenType = False Then
MsgBox ("You Havent Selected a File")
Exit Sub
End If
'Write the FileOpenType variant to two separate strings
NewProjFilePath = Left$(FileOpenType, InStrRev(FileOpenType, "\"))
NewProjFileName = Mid$(FileOpenType, InStrRev(FileOpenType, "\") + 1)
Newsheet.Name = NewProjFileName
Set s = Newsheet
'Populate spreadsheet header row with column titles from MS Project
s.Range("A1").Value = t.Number1 ***<-- Error '91' - Object variable or With block variable not set***
End Sub
Here is generic code that loops through the fields in the active task table and prints out the field headings as displayed in the table.
Sub GetTaskTableHeaders()
Dim t As Table
Set t = ActiveProject.TaskTables(ActiveProject.CurrentTable)
Dim f As TableField
For Each f In t.TableFields
If f.Field > 0 Then
Dim header As String
Dim custom As String
custom = Application.CustomFieldGetName(f.Field)
If Len(f.Title) > 0 Then
header = f.Title
ElseIf Len(custom) > 0 Then
header = custom
Else
header = Application.FieldConstantToFieldName(f.Field)
End If
Debug.Print "Field " & f.Index, header
End If
Next f
End Sub
Note that fields can be customized at the project level to be given a different title, or they can be customized at the table level. This code looks for both customizations and if neither is found, the field name is used.
Try the code below, explanation inside the code's comments:
Option Explicit
Sub PopulateSheet()
Dim Proj As MSProject.Application
Dim NewProj As MSProject.Project
Dim PjTableField As MSProject.TableField ' New Object
Dim PjTaskTable As MSProject.Table ' New Object
Dim t As MSProject.task
Dim xl As Workbook
Dim s As Worksheet
Dim Newsheet As Worksheet
Dim BookName As String
Dim FileOpenType
Dim NewProjFilePath As String, NewProjFileName As String
Set xl = ThisWorkbook
BookName = xl.Name
Set Newsheet = xl.Worksheets.Add
'Code to find and open project files
Set Proj = New MSProject.Application
MsgBox ("Please Select MS Project File for Quality Checking")
'Select Project File
FileOpenType = Application.GetOpenFilename( _
FileFilter:="MS Project Files (*.mpp), *.mpp", _
Title:="Select MS Project file", _
MultiSelect:=False)
'Detect if File is selected, if not then stop code
If FileOpenType = False Then
MsgBox ("You Havent Selected a File")
Exit Sub
End If
'Write the FileOpenType variant to two separate strings
NewProjFilePath = Left$(FileOpenType, InStrRev(FileOpenType, "\"))
NewProjFileName = Mid$(FileOpenType, InStrRev(FileOpenType, "\") + 1)
Newsheet.Name = NewProjFileName
Set s = Newsheet
' Open MS-Project File
Proj.FileOpen NewProjFilePath & NewProjFileName
Set NewProj = Proj.ActiveProject
' ===== New code Section =====
' set the Table object
Set PjTaskTable = NewProj.TaskTables(NewProj.CurrentTable)
' loop through all tablefields in table
For Each PjTableField In PjTaskTable.TableFields
If PjTableField.Field = pjTaskNumber1 Then ' check if currect field numeric value equals the numeric value of "Number1"
'Populate spreadsheet header row with column titles from MS Project
s.Range("A1").Value = PjTableField.Title ' populate "A1" with the field's title and
End If
Next PjTableField
End Sub

Call excel function in access vba

I've a sub in excel that needs to be called from access.
Excel vba
Public Function testme(value As String) As String
Dim xlpath As String
Dim concate As String
xlpath=ActiveWorkbook.Path
value = ActiveWorkbook.Name
concate = xlpath & "\" & value
Let testme = concate
End Function
i need to call above method in one of the access method.How do i call it.
Sub Connect1()
Dim xlApp As Variant
'Set xlApp = CreateObject("Excel.Application")
'this will launch a blank copy of excel; you'll have to load workbooks
'xlApp.Visible = True
Set xlApp = GetObject(, "Excel.Application")
Let ans = xlApp.Application.Run("MyXLVBAProject.MyXLVBAModule.testme", 400)
'here ans has the string "500"
End Sub
You'll probably want to use Application.Run from Excel's object model. You pass it a string such as "QuickRDA.JavaCallBacks.GetQuickTab" for the macro name, where QuickRDA is the name of the Excel VBA project, JavaCallBacks is the name of the VBA module in that VBA project, and GetQuickTab is the name of the function in that VBA module.
In Access
Sub Connect()
Dim xlApp As Variant
Set xlApp = GetObject(, "Excel.Application")
'this will connect to an already open copy of excel, a bit easier for quick & dirty testing
Let ans = xlApp.Application.Run("MyXLVBAProject.MyXLVBAModule.testme")
End Sub
In Excel
Public Function testme() As String
Dim xlpath As String
Dim concate As String
Dim value as String
xlpath = ActiveWorkbook.Path
value = ActiveWorkbook.Name
concate = xlpath & "\" & value
Let testme = concate
End Function
-or simply-
Public Function testme() As String
Let testme = ActiveWorkbook.FullName
End Function
Remember that in Excel the function testme should be put in a module whose name is MyXLVBAModule, and that the project containing the module should be called MyXLVBAProject.
So, you want to trigger an Excel function from Access, or run an Excel subroutine from Access?
To run a function, you can do something like this.
Public Function FV(dblRate As Double, intNper As Integer, _
dblPmt As Double, dblPv As Double, _
intType As Integer) As Double
Dim xl As Object
Set xl = CreateObject("Excel.Application")
FV = xl.WorksheetFunction.FV(dblRate, intNper, dblPmt, dblPv, intType)
Set xl = Nothing
End Function
To run an Excel subroutine from Access, you can do the following.
Sub RunExcelMacro()
Dim xl As Object
'Step 1: Start Excel, then open the target workbook.
Set xl = CreateObject("Excel.Application")
xl.Workbooks.Open ("C:\Book1.xlsm")
'Step 2: Make Excel visible
xl.Visible = True
'Step 3: Run the target macro
xl.Run "MyMacro"
'Step 4: Close and save the workbook, then close Excel
xl.ActiveWorkbook.Close (True)
xl.Quit
'Step 5: Memory Clean up.
Set xl = Nothing
End Sub

A couple of questions about Word macros

I need to grab a list of names from Excel and insert them into a Word document, printing one document per name. The document has some text and a bookmark called "name". The code is below.
First, I want to know if it's possible to detect how long is the list of names in the Excel spreadsheet and grab that, instead of hardcoding the number.
Second, I can't figure out how to delete the text I already put inside the document. When I insert text in a bookmark, it gets appended after the bookmark, so if I keep adding names they all stack together.
Maybe with the code this will be clearer:
Sub insertar_nombre()
Dim Excel As Excel.Application
Dim Planilla As Excel.Workbook
Dim Hoja As Excel.Worksheet
Set Excel = CreateObject("Excel.Application")
Dim Filename As String
Dim fname As Variant
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Title = "Seleccionar Documento de Excel"
.Show
For Each fname In .SelectedItems
Filename = fname
Next
End With
Set Planilla = Excel.Workbooks.Open(Filename)
Set Hoja = Planilla.Worksheets(1)
Dim Nombre As String
For Count = 2 To 10
Nombre = Hoja.Cells(Count, 1).Value
ActiveDocument.Bookmarks("name").Range.Text = Nombre
ActiveDocument.PrintOut
Next
End Sub
Forgive me if this code is obviously wrong or something, I'm just beginning with this.
I need to grab a list of names from Excel and insert them into a Word document, printing one document per name.
Why don't you simply use the mail merge feature?
the following Sub should solve this for you, but you might need to change the way your bookmark is defined.
There is more than one way to insert a Bookmark. This method requires the Bookmark to be inserted by highlighting the text, not simply positioning the cursor at a location in the text.
Sub insertar_nombre()
Dim xlWorkbook As Excel.Workbook
Dim xlWorksheet As Excel.Worksheet
Dim strFilename As String
Dim bkmName As Word.Range
Dim strBookmarkOriginalText As String
Dim lngRowLast As Long
Dim rngRowStart As Excel.Range
Dim rngRowEnd As Excel.Range
Dim rngNames As Excel.Range
Dim rngName As Excel.Range
'Open file dialog and only allow Excel files'
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Title = "Seleccionar Documento de Excel"
'Only let them select Excel files'
.Filters.Clear
.Filters.Add "Excel Documents (*.xls)", "*.xls"
'Check if a file is selected'
If .Show = True Then
'Since AllowMultiSelect is set to False, _
only one file can be selected'
strFilename = .SelectedItems(1)
Else
'No file selected, so exit the Sub'
Exit Sub
End If
End With
'Set the bookmark to a Word range (not a Bookmark object)'
Set bkmName = ActiveDocument.Bookmarks("name").Range
'Save the original text of the bookmark'
strBookmarkOriginalText = bkmName.Text
'Open the Excel file'
Set xlWorkbook = Excel.Workbooks.Open(strFilename)
Set xlWorksheet = xlWorkbook.Worksheets(1)
'Range of the first cell that contains a name'
Set rngRowStart = xlWorksheet.Cells(2, 1)
'Range of the last cell in the column'
lngRowLast = xlWorksheet.Range("A65536").End(xlUp).Row
Set rngRowEnd = xlWorksheet.Cells(lngRowLast, 1)
'Range of all cells from first name cell to last name cell'
Set rngNames = xlWorksheet.Range(rngRowStart, rngRowEnd)
'Loop through the range of names'
For Each rngName In rngNames
'Ignore any blank cells'
If rngName <> vbNullString Then
'Set the text of the bookmark range to the name from Excel'
bkmName.Text = rngName
'The above statement deleted the Bookmark, so create _
a new Bookmark using the range specified in bkmName'
ActiveDocument.Bookmarks.Add Name:="name", Range:=bkmName
'Print the document'
ActiveDocument.PrintOut
End If
Next
'Restore the orignal value of the bookmark'
bkmName.Text = strBookmarkOriginalText
ActiveDocument.Bookmarks.Add Name:="name", Range:=bkmName
'Close the Workbook without saving'
xlWorkbook.Close SaveChanges:=False
End Sub
Hope this helps.

Resources