How to create individual HTML publish pages using loop through excel spreadsheet - html

I am trying to create individual HTML pages using a loop function on an excel spreadsheet. I had been manually publishing each page but I have thousands of entries, so I need an automated method using macro. I recorded a macro with the steps I use through the manual approach shown below:
Sub HTMLexport()
Columns("A:W").Select
With ActiveWorkbook.PublishObjects.Add(xlSourceRange, _
"C:\Users\<user_name>\Desktop\Excel2HTML\Articles\1045_VSE.htm", _
"Sheet1", "$A:$W", xlHtmlStatic, _
"FileName_10067", "")
.Publish (True)
End With
Columns("W:W").Select
Selection.EntireColumn.Hidden = True
End Sub
Ultimately what I want is to be able to have Column A and the next column selected (ex. B, C, H, Etc), then have those two published into an HTML page. The name of the file I would like to be based on a cell reference. Ex. Cell W3 would have a value of 1045, and the file name be saved as 1045_VSE.htm, where _VSE is constant through the loop process. That way, each new HTML page name would increment based on the cell reference. Once the HTML page is saved, hide the column and move to the next one, rinse and repeat. Any help with this would be amazing. Thanks in advance.

This should be fairly straightforward to put inside a loop.
Here is an example. I assume that the filename will come from the first row/second column in the sub-range, you can easily modify this, or ask me how and I can revise. I also assume that the Div ID ("FileName_100067") is constant. Again, this can easily be modified if needed.
Sub HTMLinLoop()
Dim wb As Workbook: Set wb = ActiveWorkbook
Dim ws As Worksheet: Set ws = ActiveSheet
Dim rng As Range '## The full range including all columns'
Dim subRng As Range '## a variable to contain each publishObjects range'
Dim pObj As PublishObject '## A variable to contain each publishObject as we create it.'
Dim p As Long '## use this integer to iterate over the columns in rng'
Dim fileName As String '## represents just the file name to export'
Dim fullFileName As String '## the full file path for each export'
Dim divName As String '## variable for the DivID argument, assume static for now'
Set rng = ws.Range("A3:W30") '## modify as needed'
For p = 1 To rng.Columns.Count
'Identify the sub-range to use for this HTML export:'
' this will create ranges like "A:B", then "A:C", then "A:D", etc.'
Set subRng = Range(rng.Columns(1).Address, rng.Columns(p + 1).Address)
'Create the filename:'
'## modify as needed, probably using a range offset.'
fileName = subRng.Cells(1, 2).Value & "_VSE.htm"
'Concatenate the filename & path:'
'## modify as needed.'
exportFileName = "C:\Users\" & Environ("Username") & "\Desktop\" & fileName
'Create hte DIV ID:'
divName = "FileName_10067" '## modify as needed, probably using a range offset.'
'## Now, create the publish object with the above arguments:'
Set pObj = wb.PublishObjects.Add( _
SourceType:=xlSourceRange, _
fileName:=exportFileName, _
Sheet:=ws.Name, _
Source:=subRng.Address, _
HtmlType:=xlHtmlStatic, _
DivID:=divName, _
Title:="")
'## Finally, publish it!'
pObj.Publish
'## Hide the last column:'
rng.Columns(p+1).EntireColumn.Hidden = True
Next
End Sub

Related

send Enter(~) key using vba to an outside IE object

I'm stuck with the following task: from an excel file I send data (for a certain column into the sheet I send the cell values) to a specific IE object predefined.
The data is sent onto the website in a textarea field (identified onto the website through an ID:id1) using a macro. For each cell value/data added into the textarea field of the website Enter key/command need to be done/appended automatically as this will generate some of the empty input fields to be completed automatically onto the website (the code is listed below:)
I'm struggling with a method of automatically send the ENTER key onto the website into the textarea after the data is inserted
Code updated..
Sub adddata()
Dim objIE As Object
Dim objTR As Object
Dim i, j, counter As Integer
Dim lastRow As Long
counter = 1
Set objIE = GetIeByTitle("https://exampletest.com", True, True)
Dim lastRow2 As Integer
lastRow2 = Workbooks(path1).Worksheets("Test").Range("A" & Rows.Count).End(xlUp).Row
Workbooks(path1).Worksheets("Test").Activate
contor = 1
'First of all the unhidden files have to be take from the target excel file
'Selecting the unhidden lines from the excel file
For j = 1 To lastRow2
If Rows(j).EntireRow.Hidden = False Then
Workbooks(path1).Worksheets("Test").Range("A" & j & ":Z" & j).Select
Selection.Copy
ThisWorkbook.Worksheets("Test2").Range("A" & counter).PasteSpecial
counter = counter + 1
End If
Next j
'look into the new excel file containing just the unhidden lines
'Afterwards a look up through new excel file cells
For i = 2 To counter
objIE.document.getelementbyid("id1").Value = Worksheets("Test2").Range("C" & i).Value ' taking the value from the cell and adding it on the text area field
objIE.document.getelementbyid("id1").SetFocus
Application.SendKeys "~" ' sending the enter key
Application.Wait (7) ' add the delay of 7 seconds
'2nd field
objIE.document.getelementbyid("id2").Value = Worksheets("Test2").Range("D" & i).Value
'3rd field
objIE.document.getelementbyid("id3").Value = Worksheets("Test2").Range("E" & i).Value
Next i
End Sub
It looks like youre missing a closing bracket here:
Set objIE = GetIeByTitle("https://exampletest.com", True, True ***)***
Try putting braces around the tilde:
Application.SendKeys "{~}"
EDIT:
It sounds like perhaps there is code associated with the change of the text box; perhaps try:
objIE.document.getelementbyid("id1").fireevent ("onchange")

Set cell value with VBA

I scan and save images with Wia using VBA in Microsoft Access.
The filepath to the saved image should be set as the value of the current cell.
I can't figure out how to do this but it seems like an easy task after learning how to use Wia.
Here is my current code that scans a document.
Function scanImage() As String
Dim imagePath As String
Dim folder As String
folder = "C:\Users\username\Pictures\scans\"
Dim tempName, obj
Set obj = CreateObject("Scripting.FileSystemObject")
tempName = obj.GetTempName
Dim filename
filename = Now
filename = Replace(filename, ".", "_")
filename = Replace(filename, " ", "_")
filename = Replace(filename, ":", "_")
imagePath = folder & filename & ".jpg"
Dim dev As Device
Dim wiaDialog As New WIA.CommonDialog
Dim wiaImage As WIA.ImageFile
Set dev = wiaDialog.ShowSelectDevice
Set wiaImage = wiaDialog.ShowAcquireImage
wiaImage.SaveFile (imagePath)
scanImage = imagePath
End Function
As comments have said - there's no cells in Access, and definitely no active cell.
You can add a record to a database using either of the methods below, but how do you plan on extracting that information again?
In Excel you just ask for the data in cell A1 for example, but in a database you generally ask for the data from a field or fields where another field on that same record is equal to some other values (either by supplying the 'other value' directly or by referencing other tables within the database).
So, for example, in your database you'd ask for the file paths of all files scanned on a certain date, or have some kind of description field to identify the file.
This would be written something like:
SELECT FilePath FROM Table2 WHERE DescriptionField = 'MyPhoto'
Anyway, the answer to get that single text string (imagepath) into a new record in a table is:
Sub InsertValueToTable()
Dim imagepath As String
imagepath = "<file path>"
'NB: The table name is 'Table2', the field (column) within the table is called 'FilePath'.
'One way to do it:
'DoCmd.RunSQL "INSERT INTO Table2(FilePath) VALUES ('" & imagepath & "')"
'Another way to do it:
Dim rst As dao.Recordset
Set rst = CurrentDb.OpenRecordset("Table2")
With rst
.AddNew
rst!FilePath = imagepath
.Update
.Close
End With
Set rst = Nothing
End Sub
Note - if you use a Text field in the database you'll be limited to 255 characters.

docmd.TransferSpreadsheet Access --> Excel //// specify destination worksheet AND range

I have to write some Access VBA to export data from an Access query into a specific range of cells in an Excel document that has several worksheets.
I am having trouble finding the right way to specify the worksheet AND range.
Here is what I have so far:
docmd.TransferSpreadsheet(TransferType:=acExport, SpreadsheetType:=acSpreadsheetTypeExcel8, TableName:=qry_Main, _
FileName:="c:\test.xlsm", _
HasFieldNames:=False, _
Range:="Main!J9:J10")
The broken piece is Range:="Main!J9:J10"
What's the proper way to make this reference?
You can use CopyFromRecordset and automation:
Sub XLTrans()
''Reference: Microsoft ActiveX Data Object x.x Library
Dim rs As New ADODB.Recordset
Dim xl As Object ''Excel.Application
Dim wb As Object ''Workbook
Set xl = CreateObject("Excel.Application")
''Pick one
''1. New book
Set wb = xl.Workbooks.Add
''2. Existing book
Set wb = xl.Workbooks.Open("z:\docs\book1.xlsx")
''Connection relevant for 2007 or 2010
rs.Open "MyTableOrQuery", CurrentProject.AccessConnection
wb.Sheets("Sheet1").Cells(4, 5).CopyFromRecordset rs
xl.Visible = True
End Sub
Note that this will not include column headings, but you can add them as well, for example:
For i = 0 To rs.Fields.Count - 1
Worksheets("Sheet1").Cells(3, i + 5) = rs(i).Name
Next
http://msdn.microsoft.com/en-us/library/office/ff844793.aspx
http://msdn.microsoft.com/en-us/library/office/aa141565(v=office.10).aspx
You cannot use RANGE for exporting:
"
Range Optional Variant. A string expression that's a valid range of cells or the name of a range in the spreadsheet. This argument applies only to importing. Leave this argument blank to import the entire spreadsheet. When you export to a spreadsheet, you must leave this argument blank. If you enter a range, the export will fail.
"

Find and copy cells from adjacent worksheet to current worksheet

I need to create a macro (or function) to copy cells from an adjacent worksheet to the current worksheet if they meet certain criteria.
Below is the worksheet adjacent to the current worksheet that contains the Owner, Ticket, and Comments fields. I need to copy those fields to the appropriate application name and object (Concatenated as a unique ID) in the current worksheet.
Below is the current worksheet that I need to copy the above fields to. Notice that the applications are not listed in the same order. This will be the case as I never know which order the data will be in or if the same data will even be in the new worksheet.
So far I have tried this function:
=IF(INDIRECT(NextSheetName()&"!A3")&INDIRECT(NextSheetName()&"!B3") = A3&B3, INDIRECT(NextSheetName()&"!D3"), "0")
Which will work only in the case that the worksheets have the same data in the same order.
Does anyone have any idea how this can be done?
If you want to do this using VBA, try the following. The code copies matching rows from the source worksheet to the target worksheet and records the matching row on the source to the target, in case you find that useful. I named my sheets "Source" and "Target" and am assuming that you are wanting to match on the concatenation of columns A and B.
The number of rows in your source and target don't matter, nor does the order in which the matches appear.
I wrote two different versions. The first works, but I'm not crazy about it because it loops through the source range looking for a match for each value in the target. The second version uses a dictionary that is built once. Matching search terms is then done without having to loop through a range. Note that to use the dictionary, you'll need a reference to the Microsoft Scripting Runtime.
First Version: (functional, but requires multiple loops)
Sub GetTwoColumnMatches()
Dim wsrc As Worksheet
Dim wTgt As Worksheet
Dim rng As Range
Dim cell As Range
Dim lLastTargetRow As Long
Dim lMatchedRow As Long
Dim sConcat As String
Set wsrc = Sheets("Source")
Set wTgt = Sheets("Target")
lLastTargetRow = wTgt.Range("A" & wTgt.Rows.Count).End(xlUp).Row
Set rng = wTgt.Range("a2:a" & lLastTargetRow)
For Each cell In rng
sConcat = cell & cell.Offset(, 1)
lMatchedRow = Matches(sConcat)
If lMatchedRow <> 0 Then
wTgt.Range("a" & cell.Row & ":e" & cell.Row).Value = _
wsrc.Range("a" & lMatchedRow & ":e" & lMatchedRow).Value
wTgt.Range("f" & cell.Row) = lMatchedRow
End If
Next
End Sub
Function Matches(SearchFor As String) As Long
Dim wsrc As Worksheet
Dim rng As Range
Dim cell As Range
Dim lLastSourceRow As Long
Dim lSourceRow As Long
Set wsrc = Sheets("Source")
lLastSourceRow = wsrc.Range("a" & wsrc.Rows.Count).End(xlUp).Row
Set rng = wsrc.Range("a2:a" & lLastSourceRow)
Matches = 0
For Each cell In rng
If cell & cell.Offset(, 1) = SearchFor Then
Matches = cell.Row
Exit For
End If
Next
End Function
Second Version: (optimized, requires reference to Microsoft Scripting Runtime)
Sub GetTwoColumnMatches()
Dim wsrc As Worksheet
Dim wTgt As Worksheet
Dim rng As Range
Dim cell As Range
Dim srcRng As Range
Dim srcCell As Range
Dim lLastTargetRow As Long
Dim lLastSourceRow As Long
Dim lMatchedRow As Long
Dim lSourceRow As Long
Dim sConcat As String
Dim dict As Dictionary
Set wsrc = Sheets("Source")
Set wTgt = Sheets("Target")
lLastTargetRow = wTgt.Range("A" & wTgt.Rows.Count).End(xlUp).Row
Set wsrc = Sheets("Source")
lLastSourceRow = wsrc.Range("a" & wsrc.Rows.Count).End(xlUp).Row
'Create the dictionary
Set dict = New Dictionary
Set srcRng = wsrc.Range("a2:b" & lLastSourceRow)
For Each srcCell In srcRng
sConcat = srcCell & srcCell.Offset(, 1)
If Len(sConcat) > 0 Then dict.Add sConcat, srcCell.Row
Next
Set rng = wTgt.Range("a2:a" & lLastTargetRow)
For Each cell In rng
sConcat = cell & cell.Offset(, 1)
lMatchedRow = dict.Item(sConcat)
If lMatchedRow <> 0 Then
wTgt.Range("a" & cell.Row & ":e" & cell.Row).Value = _
wsrc.Range("a" & lMatchedRow & ":e" & lMatchedRow).Value
wTgt.Range("f" & cell.Row) = lMatchedRow
End If
Next
End Sub
Here's what your references will look like once you've correctly selected the Microsoft Scripting Runtime:

How do I save each sheet in an Excel 2010 workbook to separate CSV files with a macro?

This question is very similar to the previously posted question: Save each sheet in a workbook to separate CSV files
However, my requirements are slightly different in that I need to have the ability to ignore specifically named worksheets (see #2 below).
I have been successful in utilizing the solution posted in this answer: https://stackoverflow.com/a/845345/1289884 which was posted in response to the question above meets almost all of my requirements with the exception of #2 below and #3 below:
I have an excel 2010 workbook that consists of multiple worksheets and I am looking for a macro that will:
Save each worksheet to a separate comma delimited CSV file.
Ignore specific named worksheet(s) (i.e. a sheet named TOC and sheet name Lookup)
Save files to a specified folder (example: c:\csv)
Ideal Solution would additionally:
Create a zip file consisting of all of the CSV worksheets within a specified folder
Any help would be greatly appreciated.
Nick,
Given you expanded on your question with the differences, and the zip part is a significant addon I have outlined a solution below that:
Creates the CSV file, skipping specific sheets using this line Case "TOC", "Lookup"
Adds them to a Zip file. This section draws heavily on Ron de Bruin's code here
The code will create the paths under StrMain and StrZipped if they do not already exists
As the ActiveWorkbook gets sub-divided into CSV files the code tests that the ActiveWorkbook is saved prior to proceeding
On (2) I ran across an issue I have seen before in my Produce an Excel list of the attributes of all MP3 files that sit in or below the "My Music" folde where the Shell.Application errored when string variables were passed to it. So I gritted my teeth and added a hardcoding of the earlier paths for Zip_All_Files_in_Folder. I commented out my earlier variable passing to show where I tried this
VBA to save CSVS
Public Sub SaveWorksheetsAsCsv()
Dim ws As Worksheet
Dim strMain As String
Dim strZipped As String
Dim strZipFile As String
Dim lngCalc As Long
strMain = "C:\csv\"
strZipped = "C:\zipcsv\"
strZipFile = "MyZip.zip"
If Not ActiveWorkbook.Saved Then
MsgBox "Pls save " & vbNewLine & ActiveWorkbook.Name & vbNewLine & "before running this code"
Exit Sub
End If
With Application
.DisplayAlerts = False
.ScreenUpdating = False
lngCalc = .Calculation
.Calculation = xlCalculationManual
End With
'make output diretcories if they don't exist
If Dir(strMain, vbDirectory) = vbNullString Then MkDir strMain
If Dir(strZipped, vbDirectory) = vbNullString Then MkDir strZipped
For Each ws In ActiveWorkbook.Worksheets
Select Case ws.Name
Case "TOC", "Lookup"
'do nothing for these sheets
Case Else
ws.SaveAs strMain & ws.Name, xlCSV
End Select
Next
'section to run the zipping
Call NewZip(strZipped & strZipFile)
Application.Wait (Now + TimeValue("0:00:01"))
Call Zip_All_Files_in_Folder '(strZipped & strZipFile, strMain)
'end of zipping section
With Application
.DisplayAlerts = True
.ScreenUpdating = True
.Calculation = lngCalc
End With
End Sub
'Create the ZIP file if it doesn't exist
Sub NewZip(sPath As String)
'Create empty Zip File
'Changed by keepITcool Dec-12-2005
If Len(Dir(sPath)) > 0 Then Kill sPath
Open sPath For Output As #1
Print #1, Chr$(80) & Chr$(75) & Chr$(5) & Chr$(6) & String(18, 0)
Close #1
End Sub
'Add the files to the Zip file
Sub Zip_All_Files_in_Folder() '(sPath As String, ByVal strMain)
Dim oApp As Object
Set oApp = CreateObject("Shell.Application")
'Shell doesn't handle the variable strings in my testing. So hardcode the same paths :(
sPath = "C:\zipcsv\MyZip.zip"
strMain = "c:\csv\"
'Copy the files to the compressed folder
oApp.Namespace(sPath).CopyHere oApp.Namespace(strMain).items
MsgBox "You find the zipfile here: " & sPath
End Sub