Access VBA to open, edit and save Excel doc - ms-access

I have an Access DB to open, edit and save an Excel doc that works fine the first time run but if I try to alter more than one file (or the same file twice) it fails with "Run-time error '1004': Method 'Cells' of object '_Global' failed"
If I close the DB then re-open it, it again works fine for the first file altered.
Although I am not new to VBA I would say that I am a novice. Here is a snippit of the code I am using:
Code:
'Open spreadsheet and make it visible
Set xl = CreateObject("Excel.Application")
strInputFile = varItem
xl.Workbooks.Open strInputFile
xl.Visible = True
'Trying to get row count here but not working yet
'Set myRange = xl.Sheets("Sheet1").Range("C:C")
'lRowCount = Excel.Application.WorksheetFunction.CountA("Sheet1").Range("C:C")
'lRowCount = xl.WorksheetFunction.CountA(Worksheets("Sheet1").Cells(C, C))
'Debug.Print lRowCount
'strMyRange = "C:C"
'lRowCount = xl.WorksheetFunction.CountA(strMyRange)
'Debug.Print lRowCount
'lRowCount = Excel.Application.WorksheetFunction.CountA(Workbooks(strInputFile).Sheets("Sheet1").Range("C:C"))
'Debug.Print lRowCount
'Make the changes
j = 0
If Left(strFile, 4) = "xxxx" Then
myPath = "\\a\path\for\xxxx"
If InStr(1, strFile, "IQ") Then
For i = 1 To 500 'Row count not working yet
If InStr(1, Cells(i, "C").Value, myVariable) > 0 Then
Cells(i, "B") = "New Value"
j = j + 1
End If
Next
End If
End If
'Clean up
xl.Quit
Set xl = Nothing
Set objInputFile = Nothing

The Excel VBA code for using in Access should be modified. You cannot use direct calls of Excel library methods like Cell. Declare variables for Excel.Application, Workbook and Worksheet and use them for referencing worksheet cells. Avoid using Activate methods. So, in your case the code will be like this:
Dim xl As Excel.Application
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Dim lRowCount As Long
Dim myRange As Excel.Range
Set xl = CreateObject("Excel.Application")
strInputFile = varItem
Set wb = xl.Workbooks.Open(strInputFile)
Set ws = wb.Sheets("Sheet1")
lRowCount = ws.UsedRange.Rows.Count
'Make the changes
j = 0
If Left(strFile, 4) = "xxxx" Then
myPath = "\\a\path\for\xxxx"
If InStr(1, strFile, "IQ") Then
For i = 1 To lRowCount
If InStr(1, ws.Cells(i, "C").Value, myVariable) > 0 Then
ws.Cells(i, "B") = "New Value"
j = j + 1
End If
Next
End If
End If
wb.Save
'Clean up
xl.Quit
Set xl = Nothing
Don't forget to add a reference to Microsoft Excel library

Related

How to hide columns in dynamic subranges before converttohtml in emailbody in Outlook?

I am doing a macro that is formatting a data base into a table, and then select ranges from this table in order to send to different persons depending of the range.
But depending of the range sometimes I can have several column empty, I would like to add in my loop that when creating the temporary workbook, to copy paste my subtable that I wanna send, a function or a part that check if the column is empty (I have headers) and if it's the case, hide the columns concerned only for this range and then convert to HTML in my body email the range without my empty column now hidden and after the loop keeps going through my whole table.
Thanks to a previous post, my VBA code is running smoothly but as soon as I add the part which is supposed to hide column, it's not working anymore, I guess, that I am not adding it in the right place but I don't know,
I tried to add it, just after RangeToEmail and in the function that is creating the tempWB, RangetoHTML but it's not working. (see both codes after)
The code I used on a static range and which is working, to hide the column is
Dim iFirstCol As Integer, iLastCol As Integer, i As Integer`
'variables to hold the first and last column numbers
iFirstCol = Range("A2").Column
iLastCol = Range("W2").Column
LastRow = Range(Range("A2"), Range("A2").End(xlDown))
'count backwards through columns
For i = iLastCol To iFirstCol Step -1
'if all cells are blank, hide the column
If WorksheetFunction.CountA(Range(Cells(1, i), Cells(LastRow, i))) = 0 Then
Columns(i).EntireColumn.Hidden = True
End If
Next i
and here is the code I use to go from my table to the different subtable and then through TemporaryWB convert to html in my email body
Option Explicit
Sub GetNames()
Dim NameArray() As String
Dim NameRange As Range
Dim C As Range
Dim Counter As Integer
Dim NameFilter As Variant
Dim RangeToEmail As Range
Dim EmailAddress() As String
'Email Stuff
Dim objOutlook As Object
Set objOutlook = CreateObject("Outlook.application")
Dim objEmail As Object
Set NameRange = Range(Range("H2"), Range("H2").End(xlDown))
ReDim NameArray(1 To Range(Range("H2"), Range("H2").End(xlDown)).Rows.Count) ReDim EmailAddress(1 To Range(Range("H2"), Range("H2").End(xlDown)).Rows.Count)
Counter = 0
For Each C In NameRange
Counter = Counter + 1
NameArray(Counter) = C.Value
EmailAddress(Counter) = C.Offset(, 3)
Next
NameArray = ArrayRemoveDups(NameArray)
EmailAddress = ArrayRemoveDups(EmailAddress)
Counter = 0
For Each NameFilter In NameArray
Counter = Counter + 1
ActiveSheet.Range("A1").AutoFilter Field:=8, Criteria1:=NameFilter Set RangeToEmail = ActiveSheet.ListObjects("DataTable").Range
Set objEmail = objOutlook.CreateItem(olMailItem)
With objEmail .To = EmailAddress(Counter)
.Subject = "TestSubject"
.HTMLBody = "Hello, <br><br>Please see the latest report:<br><br>" & RangetoHTML(RangeToEmail)
.Display
End With
Set objEmail = Nothing
Next
ActiveSheet.Range("A1").AutoFilter
End Sub
Function ArrayRemoveDups(MyArray As Variant) As Variant
Dim nFirst As Long, nLast As Long, i As Long
Dim item As String
Dim arrTemp() As String
Dim Coll As New Collection
'Get First and Last Array Positions
nFirst = LBound(MyArray)
nLast = UBound(MyArray)
ReDim arrTemp(nFirst To nLast)
'Convert Array to String
For i = nFirst To nLast
arrTemp(i) = CStr(MyArray(i))
Next i
'Populate Temporary Collection
On Error Resume Next
For i = nFirst To nLast
Coll.Add arrTemp(i), arrTemp(i)
Next i
Err.Clear
On Error GoTo 0
'Resize Array
nLast = Coll.Count + nFirst - 1
ReDim arrTemp(nFirst To nLast) '
Populate Array
For i = nFirst To nLast
arrTemp(i) = Coll(i - nFirst + 1)
Next i
'Output Array
ArrayRemoveDups = arrTemp
End Function
Function RangetoHTML(rng As Range)
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "/" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
' Copy the range and create a workbook to receive the data.
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
' Publish the sheet to an .htm file.
With TempWB.PublishObjects.Add( _ SourceType:=xlSourceRange, _ Filename:=TempFile, _ Sheet:=TempWB.Sheets(1).Name, _ Source:=TempWB.Sheets(1).UsedRange.Address, _ HtmlType:=xlHtmlStatic)
.Publish (True)
End With
' Read all data from the .htm file into the RangetoHTML subroutine.
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.ReadAll
ts.Close RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _ "align=left x:publishsource=")
' Close TempWB. TempWB.Close savechanges:=False
' Delete the htm file.
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
First LastRow is not declared as variable properly and therfore you didn't see that
LastRow = Range(Range("A2"), Range("A2").End(xlDown))
is actually writing an array of values into LastRow. Actually your first code cannot work properly. Make sure you use Option Explicit (I recommend always to activate Option Explicit: In the VBA editor go to Tools › Options › Require Variable Declaration).
The issue is probably if your empty columns have headers too then
WorksheetFunction.CountA(Range(Cells(1, i), Cells(LastRow, i)))
will never be 0 because you included your header row 1 Cells(1, i) in your range. So if you want to exclude the header you need to change it to start with row 2 like Cells(2, i).
Finally all this code applies to ActiveSheet which is not very reliable because the active sheet can change by a single mouse click. If you can specify the worksheet precisely by a name, do so. If it really has to run on multiple sheets (so you really want to use the active one) at least make sure the active sheet does not change during the code excecutes by reading it only once into a variable Set ws = ThisWorkbook.ActiveSheet.
I would use
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1") 'name your sheet here!
'or if it really is the active sheet do
'Set ws = ThisWorkbook.ActiveSheet 'and make sure you only use `ws` from now!
'variables to hold the first and last column numbers
Dim iFirstCol As Long
iFirstCol = ws.Columns("A").Column
Dim iLastCol As Long
iLastCol = ws.Columns("W").Column
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlDown).Row
'count backwards through columns
Dim i As Long
For i = iLastCol To iFirstCol Step -1
'if all cells are blank, hide the column
If Application.WorksheetFunction.CountA(ws.Range(ws.Cells(2, i), ws.Cells(LastRow, i))) = 0 Then
ws.Columns(i).EntireColumn.Hidden = True
End If
Next i
Apply the same to the rest of your code to make it more reliable.

Webscrape a specific part of a webpage

My webscrape stopped working. The owner changed the html.
I believe it is the Set allElements = doc.getElementsByClassName("el-col el-col-8") line that needs changing.
I am trying to grab text from the webpage that includes the "52-week Range (undefined)" section. I managed to grab text from before and after but not the section I need. An example webpage is https://www.gurufocus.com/stock/gliba/summary and my code should fill my cell with "38.72 - 73.63" after I do some trimming.
I need to do it this way so I can get my head round it and change it in the future when necessary so please just focus on correcting my set line of code (assuming that is the problem!) rather than a whole new more sophisticated method as it will be beyond me. (My other set line of code does what I want it to do.)
Sub get_title_header()
Dim wb As Object
Dim doc As Object
Dim incomeStmtURLs As Variant
Dim sURL As String
Dim lastrow As Long
Dim allRowOfData As Object
Dim i As Integer
Dim allElements As IHTMLElementCollection
Dim anElement As IHTMLElement
Dim aCell As HTMLTableCell
Application.DisplayAlerts = False
Call ToggleEvents(False)
incomeStmtURLs = Range("Sheet1!h1:h2").Value
For i = 1 To UBound(incomeStmtURLs)
Set wb = CreateObject("internetExplorer.Application")
sURL = incomeStmtURLs(i, 1)
wb.navigate sURL
wb.Visible = False
While wb.Busy
Application.Wait Now + #12:00:01 AM#
DoEvents
Wend
Set doc = wb.document
On Error GoTo err_clear
Set allElements = doc.getElementsByClassName("el-col el-col-8")
While allElements.Length = 0
Application.Wait Now + #12:00:01 AM#
DoEvents
Wend
x = allElements(0).innerText
' Debug.Print x
Sheet6.Cells(i + 1, 2).Value = Trim(Replace(Mid(x, InStr(1, x, "52-Week Range (undefined)") + 25, 25), vbLf, ""))
Set allElements = doc.getElementsByClassName("fs-x-large fc-primary fw-bolder")
x = allElements(0).innerText
Sheet6.Cells(i + 1, 4).Value = Trim(Replace(Mid(x, InStr(1, x, "$") + 1, 7), vbLf, ""))
err_clear:
If Err <> 0 Then
Err.Clear
Resume Next
End If
wb.Quit
Next i
Call ToggleEvents(True)
End Sub
Sub ToggleEvents(blnState As Boolean)
Application.DisplayAlerts = blnState
Application.EnableEvents = blnState
If blnState Then Application.CutCopyMode = False
If blnState Then Application.StatusBar = False
End Sub
The page dynamically updates content as you scroll down. You likely need to scroll that part of the page into view then use grab all the elements with classname statictics-item then take the n-2 index e.g. Without the scrolling part:
Set elems = ie.document.getElementsByClassName("statictics-item")
If elems.length > 1 Then Debug.print elems(elems.length-2).innerText
For future readers (I know OP doesn't want this):
I would avoid the whole scrolling pickle, dynamic html and browser and issue an xmlhttp request and regex out the appropriate values from the javscript objects the web page uses for updating. N.B. I would probably add in validation on regex match positions.
Public Sub test()
Dim r As String
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://www.gurufocus.com/stock/gliba/summary", False
.send
r = GetMatches(.responseText, "price52wlow:(.*?),|price52whigh:(.*?),")
If r <> "NA" Then MsgBox r
End With
End Sub
Public Function GetMatches(ByVal inputString As String, ByVal sPattern As String) As String
Dim matches As Object
With CreateObject("vbscript.regexp")
.Global = True
.MultiLine = True
.IgnoreCase = True
.Pattern = sPattern
'If .test(inputString) Then
Set matches = .Execute(inputString)
If matches.Count = 2 Then
GetMatches = matches.Item(0).submatches(0) & "-" & matches.Item(1).submatches(1)
Else
GetMatches = "NA"
End If
End With
End Function
Regex:

Automatically export HTML Table from Outlook to Excel w/ VBA

I'd like to export an email that contains many tables in HTML format.
Each table is something like this:
<table class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" width="100%" style="width:100.0%;background:green">...</table>
I've added a New Rule in Outlook, so everytime I receive an email with 'specific word' in the Subject, the macro runs and saves all the tables from this email to a .xlsm file. The rule itself seems to work fine, but i'm having issues to make the macro work.
I've found many topics about exporting data from Outlook to Excel and I managed to copy email's TextBody using split (in rows), but it only worked with text, not with tables.
So I started searching the web for topics about exporting Tables, and I did find one. Although, it talks about importing Tables from Outlook using Excel VBA, not exactly what i'm trying to do. I tried to edit this code in order to work when running from Outlook, but it didn't work.
References:
Here's the code:
Option Explicit
Public Sub SalvaExcel()
'This macro writes an Outlook email's body to an Excel workbook
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim olFolder As Outlook.Folder
Dim olItems As Outlook.Items
Dim olNameSpace As Outlook.NameSpace
Dim olHTML As MSHTML.HTMLDocument: Set olHTML = New MSHTML.HTMLDocument
Dim olEleColl As MSHTML.IHTMLElementCollection
Dim xlApp As Excel.Application
Dim ExcelWkBk As Excel.Workbook
Dim FileName As String
'Dim TextBody As String
'Dim iArr() As String
Dim eRow As Integer
Dim xlUp As Integer
Dim i As Long
Dim j As Long
xlUp = -4162
'set email to be saved
Set olApp = Outlook.Application
Set olNameSpace = Application.GetNamespace("MAPI")
Set olFolder = olNameSpace.GetDefaultFolder(olFolderInbox)
Set olItems = olFolder.Items
'olItems.Sort ("[ReceivedTime]")
Set olMail = olItems(olItems.Count)
'save Outlook email's html body (tables)
With olHTML
.Body.innerHTML = olMail.HtmlBody
Set olEleColl = .getElementsByTagName("table")
End With
'set excel file to be opened
FileName = "C:\Users\rafael.kobayashi\Desktop\projeto_licitacoes\Palavras-Chave.xlsm"
'create an Excel instance
Set xlApp = Application.CreateObject("Excel.Application")
'in this instance
With xlApp
.Visible = True 'this slows down the macro, but helps during debugging
.ScreenUpdating = False 'reduces flash and increases speed
'open workbook
Set ExcelWkBk = xlApp.Workbooks.Open(FileName)
'in this workbook
With ExcelWkBk
'in [email] worksheet
With .Worksheets("email")
'find first empty row
'eRow = .Range("B" & .Rows.Count).End(xlUp).Row + 1
'write table in excel
Debug.Print olEleColl(0)
For i = 0 To olEleColl(0).Rows.Length - 1
For j = 0 To olEleColl(0).Rows(i).Cells.Length - 1
.Range("A1").Offset(i, j).Value = olEleColl(0).Rows(i).Cells(j).innerText
Next j
Next i
'resize columns (DO NOT)
'.Columns("B:C").AutoFit
End With
'close Workbook and save changes
.Close SaveChanges:=True
End With
'quit excel
.Quit
End With
Set xlApp = Nothing
Set ExcelWkBk = Nothing
Set olMail = Nothing
Set olHTML = Nothing
Set olEleColl = Nothing
End Sub
EDIT: There was a typo in the code, now it seems to be running, I can see that Excel opens then closes very quickly when I run the macro. However, when I open the workbook, the sheet where the tables were supposed to be is blank :(
EDIT2: I have tested the macro in an mail item where i inserted a random table and it worked, but it won't work with the tables in the mail that i showed.
EDIT3: I've found out that it wasn't working because the first table found didn't have any text in innerText, so I tested a macro that gets all the tables and it worked!
Change that line to this instead
For i = 0 To olEleColl(0).Rows.Length - 1
(You spelled Length wrong)
I've found out that it wasn't working because the first table found didn't have any text in innerText, so I tested a macro that gets all the tables and it worked!
Here's the code:
Public Sub SalvaExcel(item As Outlook.MailItem)
'This macro writes an Outlook email's tables to an Excel workbook
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim olFolder As Outlook.Folder
Dim olItems As Outlook.Items
Dim olNameSpace As Outlook.NameSpace
Dim olHTML As MSHTML.HTMLDocument: Set olHTML = New MSHTML.HTMLDocument
Dim olEleColl As MSHTML.IHTMLElementCollection
Dim xlApp As Excel.Application
Dim ExcelWkBk As Excel.Workbook
Dim FileName As String
Dim eRow As Long
Dim i As Long
Dim j As Long
Dim t
Dim posicao As String
'set email to be saved
'Set olApp = Outlook.Application
'Set olNameSpace = Application.GetNamespace("MAPI")
'Set olFolder = olNameSpace.GetDefaultFolder(olFolderInbox)
'Set olItems = olFolder.Items
'olItems.Sort ("[ReceivedTime]")
'the most recent one
'Set olMail = olItems(olItems.Count)
'save Outlook email's html body (tables)
With olHTML
.Body.innerHTML = item.HtmlBody
Set olEleColl = .getElementsByTagName("table")
End With
'set excel file to be opened
FileName = "C:\Users\rafael.kobayashi\Desktop\projeto_licitacoes\Palavras-Chave.xlsm"
'create an Excel instance
Set xlApp = Application.CreateObject("Excel.Application")
'in this instance
With xlApp
.Visible = True 'if True, this slows down the macro, but helps during debugging
.ScreenUpdating = False 'if False, this reduces flash and increases speed
'open workbook
Set ExcelWkBk = xlApp.Workbooks.Open(FileName)
'in this workbook
With ExcelWkBk
'in [email] worksheet
With .Worksheets("email")
'which row to start
eRow = 1
posicao = "A" & eRow
'write each table in excel
For Each t In olEleColl
For i = 0 To t.Rows.Length - 1
For j = 0 To t.Rows(i).Cells.Length - 1
'ignore any problems with merged cells etc
On Error Resume Next
.Range(posicao).Offset(i, j).Value = t.Rows(i).Cells(j).innerText
On Error GoTo 0
Next j
Next i
'define from which row the next table will be written
eRow = eRow + t.Rows.Length + 1
posicao = "A" & eRow
Next t
End With
'close Workbook and save changes
.Close SaveChanges:=True
End With
'quit excel
.Quit
End With
Set xlApp = Nothing
Set ExcelWkBk = Nothing
'Set olMail = Nothing
Set olHTML = Nothing
Set olEleColl = Nothing
End Sub
It exports all the tables from the last received email in the Outlook Inbox to an Excel file. It skips 1 row between one table and the next. Since it gets the most recent email and it runs from Outlook, it's useful to use in a New Rule, so it will be automatic, according to a defined criteria. I hope it helps other people!
edit: in order to run this macro in an Outlook Rule, it's necessary to give the following argument to the Sub, otherwise the macro won't be shown in the list of macros to be chosen for the Rule:
Public Sub SalvaExcel(item As Outlook.MailItem)
I have updated the code in this answer.
Thanks for sharing the code.
Have rectified your code to make it finally work ;)
Public Sub SalvaExcel()
'Public Sub SalvaExcel(item As Outlook.MailItem)
'This macro writes an Outlook email's tables to an Excel workbook
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim olFoldersDefault As Outlook.Folders
Dim olFolder As Outlook.Folder
Dim olItems As Outlook.Items
Dim olNameSpace As Outlook.NameSpace
Dim olHTML As MSHTML.HTMLDocument: Set olHTML = New MSHTML.HTMLDocument
Dim olEleColl As MSHTML.IHTMLElementCollection
Dim xlApp As Excel.Application
Dim ExcelWkBk As Excel.Workbook
Dim FileName As String
Dim eRow As Long
Dim i As Long
Dim j As Long
Dim t
Dim posicao As String
'set email to be saved
'Set olApp = Outlook.Application
'Set olNameSpace = Application.GetNamespace("MAPI")
'Set olFolder = olNameSpace.GetDefaultFolder(olFolderInbox)
'Set olItems = olFolder.Items
'olItems.Sort ("[ReceivedTime]")
'Set olApp = Outlook.Application
Set olNameSpace = Application.GetNamespace("MAPI")
Set newFolder = olNameSpace.GetDefaultFolder(olFolderInbox)
Set olFolder = newFolder.Folders("Projects").Folders("Management").Folders("Notifications")
Set olItems = olFolder.Items
olItems.Sort ("[ReceivedTime]")
'the most recent one
Set olMail = olItems(olItems.Count)
'MsgBox olMail
'MsgBox olMail.HTMLBody
'save Outlook email's html body (tables)
With olHTML
.Body.innerHTML = olMail.HTMLBody
Set olEleColl = .getElementsByTagName("table")
End With
'set excel file to be opened
FileName = "D:\OutlookEmails.xlsm"
'create an Excel instance
Set xlApp = Application.CreateObject("Excel.Application")
'in this instance
With xlApp
.Visible = True 'if True, this slows down the macro, but helps during debugging
.ScreenUpdating = False 'if False, this reduces flash and increases speed
'open workbook
Set ExcelWkBk = xlApp.Workbooks.Open(FileName)
'in this workbook
With ExcelWkBk
'in [email] worksheet
With .Worksheets("emails")
'which row to start
eRow = 1
posicao = "A" & eRow
'write each table in excel
For Each t In olEleColl
For i = 0 To t.Rows.Length - 1
For j = 0 To t.Rows(i).Cells.Length - 1
'ignore any problems with merged cells etc
On Error Resume Next
.Range(posicao).Offset(i, j).Value = t.Rows(i).Cells(j).innerText
On Error GoTo 0
Next j
Next i
'define from which row the next table will be written
eRow = eRow + t.Rows.Length + 1
posicao = "A" & eRow
Next t
End With
'close Workbook and save changes
.Close SaveChanges:=True
End With
'quit excel
.Quit
End With
Set xlApp = Nothing
Set ExcelWkBk = Nothing
'Set olMail = Nothing
Set olHTML = Nothing
Set olEleColl = Nothing
End Sub

Excel form to save data in access db

I have the below code for an excel form to currently save data in another excel.the only issue is that this doesn't work properly if more than 1 person are trying to send the data. Is it possible to make the code in a way that it sends data to an access db? Here my code.
Sub UpdateLogWorksheet()
Dim historyWks As Worksheet
Dim inputWks As Worksheet
Dim historyWb As Workbook '<~ target workbook
Dim nextRow As Long
Dim oCol As Long
Dim myRng As Range
Dim myCopy As String
Dim myCell As Range
'cells to copy from Input sheet - some contain formulas
myCopy = "D5,D7,D9,D11,D13"
Set inputWks = Worksheets("Input")
Set historyWb = Workbooks.Open("C:\reports\consolidated.xlsx") '<~ open target workbook and assign sheet
Set historyWks = historyWb.Worksheets("PartsData")
With historyWks
nextRow = .Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0).Row
End With
With inputWks
Set myRng = .Range(myCopy)
If Application.CountA(myRng) <> myRng.Cells.Count Then
MsgBox "Please fill in all the cells!"
Exit Sub
End If
End With
With historyWks
With .Cells(nextRow, "A")
.Value = Now
.NumberFormat = "mm/dd/yyyy hh:mm:ss"
End With
.Cells(nextRow, "B").Value = Application.UserName
oCol = 3
For Each myCell In myRng.Cells
historyWks.Cells(nextRow, oCol).Value = myCell.Value
oCol = oCol + 1
Next myCell
End With
historyWb.Save '<~ save and close the target workbook
historyWb.Close SaveChanges:=False
'clear input cells that contain constants
With inputWks
On Error Resume Next
With .Range(myCopy).Cells.SpecialCells(xlCellTypeConstants)
.ClearContents
Application.GoTo .Cells(1) ', Scroll:=True
End With
On Error GoTo 0
End With
End Sub
You can use this code to put data from Excel to an AccessDB:
Option Explicit
Dim con, rst, t0, i, s, xx, n
Const adUseClient = 3
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const useTransaction = True
Set con = CreateObject("ADODB.Connection")
con.CursorLocation = adUseClient
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=e:\0\a\db1.accdb;"
Set rst = CreateObject("ADODB.Recordset")
rst.Open "SELECT * FROM Table1", con, adOpenStatic, adLockOptimistic
If useTransaction Then
con.BeginTrans
End If
i = 1
For i = 1 To Range("Dati").Rows.Count
rst.AddNew
rst("FirstName").Value = Range("Dati").Cells(i, 1).Value
rst("LastName").Value = Range("Dati").Cells(i, 2).Value
rst("Birday").Value = Range("Dati").Cells(i, 3).Value
rst.Update
Next
If useTransaction Then con.CommitTrans
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
And put all the data inside Table1. All the data are taken from a Range named Dati.
I you have formula and you want to save formula use:
Range("Dati").Cells(i, 1).Formula
With This code you put ONLY the data from an Excel Files into a AccessDB file without check double data ...

How can I find specified data in a excel row using access vba

I'm trying to find specified data in a excel row. Like from row range A1:A1J, only one cell is having data "Process" . if i find that data in a given range, i need to pop up the message "Found" Here is my code
Dim ExcelApp As New Excel.Application
Dim ExcelBook As New Excel.Workbook
Dim rng As Excel.Range
Dim rngDefine As Excel.Range
Set ExcelBook = ExcelApp.Workbooks.Open("C\temp\find.xlsm")
ExcelApp.Visible = False
'Define your own Range
Set rngDefine = ExcelBook.Worksheets("Datatab").Range("A1:AJ1")
'ExcelBook.Worksheets("Datatab").Range ("A1:AJ1")
Set c = .Find("Process", LookIn:=xlValues)
For Each rng In rngDefine
If c = "Process" Then
MsgBox "Found"
End If
Next
ExcelApp.Quit
Set ExcelApp = Nothing
Not working. Any furthur code i need to add?
First approach (slighlty faster):
Set rngDefine = ExcelBook.Worksheets("Datatab").Range("A1:AJ1")
If IsError(ExcelApp.Match("Process", rngDefine, 0)) Then
MsgBox "Not found"
Else
MsgBox "Found"
End If
Second approach:
Dim c As Excel.Range
Set rngDefine = ExcelBook.Worksheets("Datatab").Range("A1:AJ1")
Set c = rngDefine.Find(What:="Process", LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)
If c Is Nothing Then
MsgBox "Not found"
Else
MsgBox "Found"
End If