VBScript enable editing in Excel file & save as - vba

Set obj = CreateObject("Excel.Application")
obj.Visible = False
Set objwbk = obj.Workbooks.Open("File Link")
obj.DisplayAlerts = False
objwbk.SaveAs "C:\Data.xlsx"
Set obj1 = obj.Workbooks.Open("C:\Data.xlsx")
obj1.Visible = True
I have the above code to create a copy of the file on SharePoint. I am able to open the file but it does not make a copy because the file is opened in readonly mode. I am unable to figure out how to use the ActiveProtectedWindow.edit method here to be able to successfully achieve my objective.

Maybe something like this:
Set obj = CreateObject("Excel.Application")
obj.Visible = False
obj.DisplayAlerts = False
Set objwbk = obj.Workbooks.Open("File Link")
If objwbk.Application.ProtectedViewWindows.Count > 0 Then
objwbk.Application.ActiveProtectedViewWindow.Edit
End If
objwbk.SaveAs "C:\Data.xlsx"
Set obj1 = obj.Workbooks.Open("C:\Data.xlsx")
obj1.Visible = True

Related

How do I save a docx as html?

I want to save a docx (Word 2007) as a html file with the accompanying files in a subfolder.
To see how to do that, I have just done that in Word 2007 and recorded a macro.
It recorded everything except the saving:
Sub Makro3()
With ActiveDocument.WebOptions
.RelyOnCSS = True
.OptimizeForBrowser = True
.OrganizeInFolder = True
.UseLongFileNames = True
.RelyOnVML = False
.AllowPNG = True
.ScreenSize = msoScreenSize800x600
.PixelsPerInch = 96
.Encoding = 65001
End With
With Application.DefaultWebOptions
.UpdateLinksOnSave = True
.CheckIfOfficeIsHTMLEditor = False
.CheckIfWordIsDefaultHTMLEditor = False
.AlwaysSaveInDefaultEncoding = False
.SaveNewWebPagesAsWebArchives = True
End With
End Sub
As I want to do the same in VB6, I re-wrote the code replacing the enum as it was unavailable in VB6 and added a SaveAs line.
However, this saved the docx obviously as a docx again, just with a different extension (.html).
What am I doing wrong?
Public Sub pCreateHtml(ByVal uPath As String)
Dim oWord As New Word.Application
Set oWord = New Word.Application
Dim oDoc As Word.Document
Set oDoc = oWord.Documents.Open(uPath, True, True)
With oDoc.WebOptions
.RelyOnCSS = True
.OptimizeForBrowser = True
.OrganizeInFolder = True
.UseLongFileNames = True
.RelyOnVML = False
.AllowPNG = True
.ScreenSize = 3 'msoScreenSize800x600
.PixelsPerInch = 96
.encoding = 65001
End With
With oDoc.Application.DefaultWebOptions
.UpdateLinksOnSave = True
.CheckIfOfficeIsHTMLEditor = False
.CheckIfWordIsDefaultHTMLEditor = False
.AlwaysSaveInDefaultEncoding = False
.SaveNewWebPagesAsWebArchives = True
End With
oDoc.SaveAs Replace(uPath, ".docx", ".html")
oDoc.Saved = True
oDoc.Close
oWord.Quit
Set oWord = Nothing
End Sub
oDoc.SaveAs2 FileName:=Replace(uPath, ".docx", ".html"), FileFormat:=wdFormatHTML
//value of wdFormatHTML is 8

Print Preview without opening Excel application [VB.net]

In VB.net Can I Print Preview without show Excel application? I have looked for this in many places and haven't found the answer.
Now I use this method.
Dim XSh As Object = CreateObject("excel.application")
XSh.workbooks.open("D:\WP\formPrint.xlsx")
XSh.visible = True
For i As Integer = 0 To count
XSh.worksheets(1).range("A21").value = DataGridView1.Rows(i).Cells(0).Value
XSh.worksheets(1).range("A22").value = DataGridView1.Rows(i).Cells(1).Value
XSh.worksheets(1).range("A23").value = DataGridView1.Rows(i).Cells(2).Value
XSh.worksheets(1).range("A24").value = DataGridView1.Rows(i).Cells(3).Value
XSh.Sheets.PrintPreview()
XSh.Sheets.PrintOut()
Next i
XSh.workbooks(1).close(SaveChanges:=False)
XSh.application.Quit
and I've tried to change
XSh.visible = False
It's don't show any things. I want to show just Print Preview don't show excel application file. How Can I do?
The Print Preview is part of the Excel Application, so it will only show when you set XsH.visible = true You can also only set it to true right before you show the Print Preview and set it back to false when it's printed.
Dim XSh As Object = CreateObject("excel.application")
XSh.workbooks.open("D:\WP\formPrint.xlsx")
XSh.visible = False
For i As Integer = 0 To count
XSh.worksheets(1).range("A21").value = DataGridView1.Rows(i).Cells(0).Value
XSh.worksheets(1).range("A22").value = DataGridView1.Rows(i).Cells(1).Value
XSh.worksheets(1).range("A23").value = DataGridView1.Rows(i).Cells(2).Value
XSh.worksheets(1).range("A24").value = DataGridView1.Rows(i).Cells(3).Value
XSh.visible = True
XSh.Sheets.PrintPreview()
XSh.Sheets.PrintOut()
XSh.visible = False
Next i
XSh.workbooks(1).close(SaveChanges:=False)
XSh.application.Quit

Macro unable to save results when it is made to run using vbscript

I've created a macro to scrape the title of posts from a webpage. The macro runs fine when I try it manually.
However, my intention is to run and save the result using a .vbs file which will be executed through a .bat file so that I can ultimately make use of it through windows task scheduler.
When I click on this .bat file to check whether it will work at all, It does open that macro using .vbs and scrape the content as it is supposed to.
The only problem I'm facing is that I can't make the .vbs file save the result in that workbook. How can I save the result?*
.vbs contains:
RunMacro
Sub RunMacro()
Dim xl, path, xlBook
path = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".")
Set xl = CreateObject("Excel.application")
Set xlBook = xl.Workbooks.Open(path & "\basicScraper.xlsm", 0, True)
xl.Application.Visible = False
xl.DisplayAlerts = False
xl.Application.Run "basicScraper.xlsm!MyMacro.GetPosts"
xl.ActiveWorkbook.Save
xl.ActiveWindow.Close
End Sub
.bat contains:
cscript macro.vbs "C:\Users\WCS\Desktop\vba scheduler\macro.vbs"
This is the macro I'm working with (module name: MyMacro):
Sub GetPosts()
Dim S$, r&, post As Object
With New XMLHTTP
.Open "GET", "https://stackoverflow.com/questions", False
.send
S = .responseText
End With
With New HTMLDocument
.body.innerHTML = S
For Each post In .getElementsByClassName("question-hyperlink")
r = r + 1: Cells(r, 1) = post.innerText
Next post
End With
End Sub
#robots.txt
You want to use the Windows Task Scheduler, create a task calling the .vbs
The .vbs should look like
Set XLObj = CreateObject("Excel.Application")
XLObj.visible = true
XLObj.Workbooks.Open "T:\he\path\to\basicScraper.xlsm"
XLObj.Run "'T:\he\path\to\basicScraper.xlsm'!MyMacro.GetPosts"
XLObj.quit
set XLObj = nothing
If I understand your code correctly, you try to insert the inner text of each link into some cells: Try to specify where exactly you want to put it (e.g. Worksheets"(Book 1").Cells(r, 1)).
Dim xHttp As MSXML2.XMLHTTP
Dim hDoc As MSHTML.HTMLDocument
Dim objCollection As Object
Dim objElement As Object
Dim strLink As String
Set xHttp = New MSXML2.XMLHTTP
xHttp.Open "GET", "https://stackoverflow.com/questions", False
xHttp.send
Do Until xHttp.READYSTATE = 4
DoEvents
Loop
If xHttp.Status = 200 Then
Set hDoc = New MSHTML.HTMLDocument
hDoc.body.innerHTML = xHttp.responseText
Set objCollection = hDoc.getElementsByClassName("question-hyperlink")
For Each objElement In objCollection
strLink = objElement.InnerText
Worksheets("Book 1").Cells(r, 1) = strLink
r = r + 1
Next
End If
ActiveWorkbook.Save
You should find your results in Book 1, rows 1 to n.
Found out the solution!!!
The .bat file should contain:
#echo off
echo %~dp0
cd /d %~dp0
"C:\Users\WCS\Desktop\New folder\macro.vbs" "C:\Users\WCS\Desktop\New folder\basicScraper.xlsm"
And the .vbs file should contain:
Dim xl, args
Set args = Wscript.Arguments
Set xl = CreateObject("Excel.application")
xl.Workbooks.Open args(0)
xl.Application.Visible = False
xl.Application.Run "GetPosts"
xl.ActiveWorkbook.Save
xl.ActiveWorkbook.Close
xl.Quit
The basicScraper.xlsm should be as it is. That's it.
Now, putting the complete address of the .bat
file's location to the schedulers program/script inputbox in Action tab will do the trick.
Post script: I kept all three files .bat, .vbs and .xlsm in a single folder before execution and got the result as expected.

Saving multiple e-mails to pdf with PDFMAKER

I'm brand spanking new to VBA. But I've programmed a bit in SAS, just a bit in Assembler (mainframe and PC), Word Perfect (macros), a bit in Java, HTML, other stuff. What I do is, when I have a problem and I think I can program it, I look for code on the internet and adjust it to fit my needs. I have read a little bit of VBA programming. What I'm trying to do is make a macro to save a bunch of Outlook e-mail messages with PDFMAKER. I've come up with the below, so far. When I step the program, pmkr2 gets assigned type "ObjectPDFMaker" and stng gets assigned type "ISettings". So far, so good. Then I try to set stng and can't do it. I get the error "Method or data member not found." If I get rid of Set it highlights .ISettings and I get the same error. I go into F2 and the AdobePDFMakerforOffice library is there, and the class ISettings is there, but I can't seem to set stng. I'm wa-a-a-ay frustrated. Please help.
Sub ConvertToPDFWithLinks()
Dim pmkr2 As Object
Set pmkr2 = Application.COMAddIns.Item(6).Object ' Assign object reference.
Dim pdfname As String
pdfname = "C:\stuff\stuff\tester.pdf"
Dim stng As AdobePDFMakerForOffice.ISettings
Set stng = AdobePDFMakerForOffice.ISettings
stng.AddBookmarks = True
stng.AddLinks = True
stng.AddTags = True
stng.ConvertAllPages = True
stng.CreateFootnoteLinks = True
stng.CreateXrefLinks = True
stng.OutputPDFFileName = pdfname
stng.PromptForPDFFilename = False
stng.ShouldShowProgressDialog = True
stng.ViewPDFFile = False
pmkr.GetCurrentConversionSettings stng
pmkr2.CreatePDFEx stng, 0
Set pmkr2 = Nothing ' Discontinue association.
End Sub
I updated your code a little. See if this has any affect:
Sub ConvertToPDFWithLinks()
Dim pmkr2 As AdobePDFMakerForOffice.PDFMaker
'Set pmkr2 = Application.COMAddIns.Item(6).Object ' Assign object reference.
Set pmkr2 = Nothing
For Each a In Application.COMAddIns
If InStr(UCase(a.Description), "PDFMAKER") > 0 Then
Set pmkr2 = a.Object
Exit For
End If
Next
If pmkr2 Is Nothing Then
MsgBox "Cannot Find PDFMaker add-in", vbOKOnly, ""
Exit Sub
End If
Dim pdfname As String
pdfname = "C:\stuff\stuff\tester.pdf"
Dim stng As AdobePDFMakerForOffice.ISettings
pmkr2.GetCurrentConversionSettings stng
stng.AddBookmarks = True
stng.AddLinks = True
stng.AddTags = True
stng.ConvertAllPages = True
stng.CreateFootnoteLinks = True
stng.CreateXrefLinks = True
stng.OutputPDFFileName = pdfname
stng.PromptForPDFFilename = False
stng.ShouldShowProgressDialog = True
stng.ViewPDFFile = False
pmkr2.CreatePDFEx stng, 0
Set pmkr2 = Nothing ' Discontinue association.
End Sub
The main changes were in how the addin is obtained and in how stng is created.

VBS to compile information from multiple excel files into one

I'm working on VBScript to move all the information from multiple excel files into one sheet on a master excel file.
It would basically be 1000-2000 rows of information and about 20 columns. There would be about 5-6 total excel files in the directory. All of the information is on the first tab, I essentially just need to copy and paste it over without overwriting the previously copy and pasted data.
This is what I have so far, the issue I'm running into is that it copies over the previous excel sheets data in the master file with the most recent excel sheet's data. I need it to go to the next open cell.
Const xlFilterCopy = 2
Const xlUp = -4162
Const xlDown = -4121
strPathSrc = "C:\test" ' Source files folder
strMaskSrc = "*.xlsx" ' Source files filter mask
iSheetSrc = 1 ' Sourse sheet index or name
'iColSrc = 1 ' Source column index, e. g. 7 for "G"
strPathDst = "C:\test\Results\Results.xlsx" ' Destination file
'iColDst = 1 ' Destination column index
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set objWorkBookDst = objExcel.Workbooks.Open(strPathDst)
Set objSheetTmp = objWorkBookDst.Worksheets.Add
'objSheetTmp.Cells(1, iColDst).Value = "TempHeader"
Set objShellApp = CreateObject("Shell.Application")
Set objFolder = objShellApp.NameSpace(strPathSrc)
Set objItems = objFolder.Items()
objItems.Filter 64 + 128, strMaskSrc
objExcel.DisplayAlerts = False
For Each objItem In objItems
Set objWorkBookSrc = objExcel.Workbooks.Open(objItem.Path)
Set objSheetSrc = objWorkBookSrc.Sheets(iSheetSrc)
Set objRangeSrc = objSheetSrc.UsedRange
Set ObjSheetDst = objWorkBookDst.Worksheets.Add
objRangeSrc.AdvancedFilter xlFilterCopy, , objSheetDst.Cells(1, 1), False
objSheetSrc.Delete
objWorkBookSrc.Close
Next
Here you are!
strPathSrc = "C:\test" ' Source files folder
strMaskSrc = "*.xlsx" ' Source files filter mask
iSheetSrc = 1 ' Sourse sheet index or name
strPathDst = "C:\test\Results\Results.xlsx" ' Destination file
iSheetDst = 1 ' Destination sheet index or name
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set objWorkBookDst = objExcel.Workbooks.Open(strPathDst)
Set objSheetDst = objWorkBookDst.Sheets(iSheetDst)
Set objShellApp = CreateObject("Shell.Application")
Set objFolder = objShellApp.NameSpace(strPathSrc)
Set objItems = objFolder.Items()
objItems.Filter 64 + 128, strMaskSrc
objExcel.DisplayAlerts = False
For Each objItem In objItems
Set objWorkBookSrc = objExcel.Workbooks.Open(objItem.Path)
Set objSheetSrc = objWorkBookSrc.Sheets(iSheetSrc)
GetUsedRange(objSheetSrc).Copy
Set objUsedRangeDst = GetUsedRange(objSheetDst)
iRowsCount = objUsedRangeDst.Rows.Count
objWorkBookDst.Activate
objSheetDst.Cells(iRowsCount + 1, 1).Select
objSheetDst.Paste
objWorkBookDst.Application.CutCopyMode = False
objWorkBookSrc.Close
Next
Function GetUsedRange(objSheet)
With objSheet
Set GetUsedRange = .Range(.Cells(1, 1), .Cells(.UsedRange.Row + .UsedRange.Rows.Count - 1, .UsedRange.Column + .UsedRange.Columns.Count - 1))
End With
End Function
You can use the macro recorder to record what you want.
Turn recording on. Press End key then Down Arrow (or whatever direction you want to go). Then down arrow again to the blank cell.
Look at your vba code and convert to vbs (macro recoder uses a experimental basic syntax that didn't take off so vbscript didn't support it).
Record the steps in excel macro recorder. You have to rewrite it a bit because it uses a type of syntax that vbs doesn't.
Here's an example
This applies (I don't have a medium9) xlRangeAutoFormatAccounting4 in vba.
Selection.AutoFormat Format:=xlRangeAutoFormatAccounting4, Number:=True, _
Font:=True, Alignment:=True, Border:=True, Pattern:=True, Width:=True
So first look up constants in vba's object browser. eg; xlRangeAutoFormatAccounting4 = 17
Then look the function up in object browser and look at the bottom for the function definition,.
EG; Function AutoFormat([Format As XlRangeAutoFormat = xlRangeAutoFormatClassic1], [Number], [Font], [Alignment], [Border], [Pattern], [Width])
So the vba becomes in vbs (and vbs works in vba) (and as you can see you can work out the correct way without needing to look the function up usually)
Selection.AutoFormat 17, True, True, True,True, True, True
So your code becomes
objXLWs.Range("A3").CurrentRegion.Select.AutoFormat 17, True, True, True,True, True, True
Why would you do it in vbscript rather than vba. Using vba you can record large parts of your code and vbscript is legal vba syntax, so you can continue to write exactly the same code as in vbscript. VBA runs inprocess while vbs is out of proocess (slow - pretends to use a network to communicate). In VBA you can early bind (set xlApp = excel.application) rather than late bind (set xlapp = CreateObject("Excel.Application") as late binding requires a conversation before EVERY function call.