I have a excel file on onedrive location and I have written a function first to replace the "/" with "\" in the file sharepoint path.
However I am trying to open the file using below syntax, but unable to open
Set objLogExcel = CreateObject("Excel.Sheet")
Set objLogWorkbook = objLogExcel.Application.Workbooks.Open(path,False,False)
The above line is adding .xlsx extension in the file path, any suggestion ?
Try this way, please:
Firstly, manually open the workbook in discussion;
In the open workbook VBE put the next code, in any module:
Sub testFullName()
Debug.Print ThisWorkbook.FullName
End Sub
In this way you will have the online characteristic full name. Something like this: "https://d.docs.live.net/fdb7a15aac1d9134/TestWorkbook.xlsx".
Copy the above full name like it is and put it in the next Sub:
Sub testOpenWBOneDrive()
Dim wbFullName, objLogExcel As Object
Set objLogExcel = CreateObject("Excel.Application")
objLogExcel.Visible = True
wbFullName = "https://d.docs.live.net/fdb7a15aac1d9134/TestWorkbook.xlsx"
objLogExcel.Workbooks.Open (wbFullName)
End Sub
Of course, you must replace the example full path with yours, obtained as explained above...
Edited: In order to be able to use the code for both cases (Online - Offline) you have to proceed in the next way:
Determine if an internet connection exists:
Copy, please the next function declaration on top of your module (in the declarations area):
Private Declare PtrSafe Function InternetGetConnectedState Lib "wininet.dll" _
(ByRef dwflags As Long, ByVal dwReserved As Long) As Long
Use the next function in that module:
Private Function isInternetConON() As Boolean
isInternetConON = InternetGetConnectedState(0&, 0&)
End Function
Then, use the next code to deal with OneDrive workbook opening, even offline:
Private Sub testOpenOneDriveOnlineOffline()
Dim sfilename As String, Xl As Object, xlsheet As Object
sfilename = "https://d.docs.live.net/fdb7a15aac1d9134/Test.xlsm"
Set Xl = CreateObject("Excel.Application") ' or Set xl = CreateObject("Excel.Sheet")
Xl.Visible = True
If isInternetConON Then
Set xlsheet = Xl.Workbooks.Open(fileName:=sfilename, ReadOnly:=False)
Else
'In case of internet connection beeing down:
'Note: It works only if you uncheck:
'OneDrive -> More -> Settings -> Office "Use Office applications to sync Office files that I open!
Dim sLocalODPath As String
sLocalODPath = Environ("onedrive") & "\" 'If your workbook is not in the OneDrive folder root,
'you have to add the other folder(s), to build the path
sfilename = Right(sfilename, Len(sfilename) - InStrRev(sfilename, "/")) ': Debug.Print sfilename: Stop
Set xlsheet = Xl.Workbooks.Open(fileName:=sLocalODPath & sfilename, ReadOnly:=False)
End If
End Sub
Related
I want to update a read-only workbook from the file "Data.xlsx".
I change the file in another application in a read-write workbook.
When I try to close the read-only workbook after updating it, an error accours.
This is my code:
Option Explicit
Public xlApp As New Application
Public wb_readWrite As Workbook
Public wb_readOnly As Workbook
Sub main()
Dim path As String
path = ThisWorkbook.path & "\Data.xlsx"
Set wb_readOnly = Workbooks.Open(path, readOnly:=True)
Set wb_readWrite = xlApp.Workbooks.Open(path, readOnly:=False)
wb_readWrite.Sheets(1).Cells(1, 1) = InputBox("Input your data")
wb_readWrite.Save
MsgBox "Update Now"
wb_readOnly.UpdateFromFile
wb_readWrite.Close
wb_readOnly.Close 'Error is here
Set wb_readWrite = Nothing
Set wb_readOnly = Nothing
End Sub
Looks like calling UpdateFromFile reloads the workbook and breaks any existing VBA references to the workbook - you need to re-establish any references after the update.
So you could use a wrapper like this for example:
Sub ReloadWorkbook(wb As Workbook)
Dim app As Application, nm As String
Set app = wb.Application 'in case in a different instance of Excel
nm = wb.Name
wb.UpdateFromFile
Set wb = app.Workbooks(nm)
End Sub
and call
ReloadWorkbook wb_readOnly
instead of wb_readOnly.UpdateFromFile
I'm currently writing a macro that will allow you to select a folder, set bounds, and then loop through some numbers to read in all of a certain file type. (Excel in this instance.)
You can see that right here
Dim StringP1 As String
Dim iterator As Integer
Dim StringP2 As String
Dim i As Integer
Dim final As Integer
'number of files
final = 5
'main folder
StringP1 = " FOLDER NAME "
StringP2 = ".xls"
i = 1
While i < final
iterator = 1
FileName = StringP1 & iterator & StringP2
Call attempt1(FileName)
Call attempt2(FileName)
i = (i + 1)
iterator = (iterator + 1)
Wend
when it loads into my subs it uses this code
Sub attempt1(FN As String)
Dim Excel As New Excel.Application
Dim FileName As String
Set XL = CreateObject("Excel.Application")
Set MyRec = CurrentDb.OpenRecordset("Infor")
Excel.Workbooks.Open (FN)
Then it goes through some code, and eventually ends up exiting the subroutine.
Everything I've tried seems to fail.
I've been messing with this for a few hours, using various things I've found from Stackoverflow and other VBA sites, but nothing seems to work.
I've tried using
excel.workbooks.close savechanges:=false
workbook.close
workbooks.close
.
.
.
I'm curious if anyone knows a good way to exit all of these EXCEL.EXE that open?
If I understand correctly you are trying to close all workbooks (Excel files).
Proper way to close single workbook by its name:
XL.Workbooks("filename.xls").Close Savechanges:=False
If you have many workbooks to close you may use a cycle like this:
Public Sub WorkWithExcel()
Dim XL As New Excel.Application, WB As Excel.Workbook
' Open Excel file:
XL.Workbooks.Open ("my_file.xls")
' Open another Excel file
XL.Workbooks.Open ("another my file.xls")
' do some work with this files
' ...
' For every file in our application:
For Each WB In XL.Workbooks
' Close file without saving changes:
WB.Close savechanges:=False
Next WB
' Close Excel applicatioin:
XL.Quit
' Clear object:
Set XL = Nothing
End Sub
I have been doing checks with worksbooks for things like if the sheet exists or what is in a cell without opening the workbook using this command
f = "'" & strFilePath1 & "[" & strFileType & "]" & strSheetName & "'!" & Range(strCell).Address(True, True, -4150)
CheckCell = Application.ExecuteExcel4Macro(f)
and it has been working well but now i am wanting to check if the sheet is Password protected without opening but haven't been successful. Anyone know if this is possible?
Thanks for help in advance
Yes! It is possible. I discovered how to do it long time ago. I doubt this is mentioned anywhere in the web...
Basic Introduction: As you are aware, Microsoft Excel up until 2007 version used a proprietary binary file format called Excel Binary File Format (.XLS) as its primary format. Excel 2007 onwards uses Office Open XML as its primary file format, an XML-based format that followed after a previous XML-based format called "XML Spreadsheet" ("XMLSS"), first introduced in Excel 2002.
Logic: To understand how this works, do the following
Create a new Excel file
Ensure it has at least 3 sheets
Protect the 1st sheet with a blank password
Leave the 2nd sheet unprotected
Protect the 3rd sheet using any password
Save the file, say, as Book1.xlsx and close the file
Rename the file to, say, Book1.Zip
Extract the contents of the zip
Go to the folder \xl\worksheets
You will see that all the sheets from the workbook has been saved as Sheet1.xml,Sheet2.xml and Sheet3.xml
Right click on the sheets and open it in notepad/notepad++
You will notice that all the sheets you protected has one word <sheetProtection as shown below
So if we can somehow check if the relevant sheet has that word then we can ascertain whether the sheet is protected or not.
Code:
Here is a function which can help you in what you want to achieve
'~~> API to get the user temp path
Private Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" _
(ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Private Const MAX_PATH As Long = 260
Sub Sample()
'~~> Change as applicable
MsgBox IsSheetProtected("Sheet2", "C:\Users\routs\Desktop\Book1.xlsx")
End Sub
Private Function IsSheetProtected(sheetToCheck As Variant, FileTocheck As Variant) As Boolean
'~~> Temp Zip file name
Dim tmpFile As Variant
tmpFile = TempPath & "DeleteMeLater.zip"
'~~> Copy the excel file to temp directory and rename it to .zip
FileCopy FileTocheck, tmpFile
'~~> Create a temp directory
Dim tmpFolder As Variant
tmpFolder = TempPath & "DeleteMeLater"
'~~> Folder inside temp directory which needs to be checked
Dim SheetsFolder As String
SheetsFolder = tmpFolder & "\xl\worksheets\"
'~~> Create the temp folder
Dim FSO As Object
Set FSO = CreateObject("scripting.filesystemobject")
If FSO.FolderExists(tmpFolder) = False Then
MkDir tmpFolder
End If
'~~> Extract zip file in that temp folder
Dim oApp As Object
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(tmpFolder).CopyHere oApp.Namespace(tmpFile).items
'~~> Loop through that folder to work with the relevant sheet (file)
Dim StrFile As String
StrFile = Dir(SheetsFolder & sheetToCheck & ".xml")
Dim MyData As String, strData() As String
Dim i As Long
Do While Len(StrFile) > 0
'~~> Read the xml file in 1 go
Open SheetsFolder & StrFile For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData() = Split(MyData, vbCrLf)
For i = LBound(strData) To UBound(strData)
'~~> Check if the file has the text "<sheetProtection"
If InStr(1, strData(i), "<sheetProtection", vbTextCompare) Then
IsSheetProtected = True
Exit For
End If
Next i
StrFile = Dir
Loop
'~~> Delete temp file
On Error Resume Next
Kill tmpFile
On Error GoTo 0
'~~> Delete temp folder.
FSO.deletefolder tmpFolder
End Function
'~~> Get User temp directory
Function TempPath() As String
TempPath = String$(MAX_PATH, Chr$(0))
GetTempPath MAX_PATH, TempPath
TempPath = Replace(TempPath, Chr$(0), "")
End Function
Note: This has been tested for .xlsx and .xlsm files.
I want to collect data from different files and insert it into a workbook doing something like this.
Do While THAT_DIFFERENT_FILE_SOMEWHERE_ON_MY_HDD.Cells(Rand, 1).Value <> "" And Rand < 65536
then 'I will search if the last row in my main worksheet is in this file...
End Loop
If the last row from my main worksheet is in the file, I'll quit the While Loop. If not, I'll copy everything. I'm having trouble finding the right algorithm for this.
My problem is that I don't know how to access different workbooks.
The best (and easiest) way to copy data from a workbook to another is to use the object model of Excel.
Option Explicit
Sub test()
Dim wb As Workbook, wb2 As Workbook
Dim ws As Worksheet
Dim vFile As Variant
'Set source workbook
Set wb = ActiveWorkbook
'Open the target workbook
vFile = Application.GetOpenFilename("Excel-files,*.xls", _
1, "Select One File To Open", , False)
'if the user didn't select a file, exit sub
If TypeName(vFile) = "Boolean" Then Exit Sub
Workbooks.Open vFile
'Set targetworkbook
Set wb2 = ActiveWorkbook
'For instance, copy data from a range in the first workbook to another range in the other workbook
wb2.Worksheets("Sheet2").Range("C3:D4").Value = wb.Worksheets("Sheet1").Range("A1:B2").Value
End Sub
You might like the function GetInfoFromClosedFile()
Edit: Since the above link does not seem to work anymore, I am adding alternate link 1 and alternate link 2 + code:
Private Function GetInfoFromClosedFile(ByVal wbPath As String, _
wbName As String, wsName As String, cellRef As String) As Variant
Dim arg As String
GetInfoFromClosedFile = ""
If Right(wbPath, 1) <> "" Then wbPath = wbPath & ""
If Dir(wbPath & "" & wbName) = "" Then Exit Function
arg = "'" & wbPath & "[" & wbName & "]" & _
wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1)
On Error Resume Next
GetInfoFromClosedFile = ExecuteExcel4Macro(arg)
End Function
Are you looking for the syntax to open them:
Dim wkbk As Workbook
Set wkbk = Workbooks.Open("C:\MyDirectory\mysheet.xlsx")
Then, you can use wkbk.Sheets(1).Range("3:3") (or whatever you need)
There's very little reason not to open multiple workbooks in Excel. Key lines of code are:
Application.EnableEvents = False
Application.ScreenUpdating = False
...then you won't see anything whilst the code runs, and no code will run that is associated with the opening of the second workbook. Then there are...
Application.DisplayAlerts = False
Application.Calculation = xlManual
...so as to stop you getting pop-up messages associated with the content of the second file, and to avoid any slow re-calculations. Ensure you set back to True/xlAutomatic at end of your programming
If opening the second workbook is not going to cause performance issues, you may as well do it. In fact, having the second workbook open will make it very beneficial when attempting to debug your code if some of the secondary files do not conform to the expected format
Here is some expert guidance on using multiple Excel files that gives an overview of the different methods available for referencing data
An extension question would be how to cycle through multiple files contained in the same folder. You can use the Windows folder picker using:
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
If .Selected.Items.Count = 1 the InputFolder = .SelectedItems(1)
End With
FName = VBA.Dir(InputFolder)
Do While FName <> ""
'''Do function here
FName = VBA.Dir()
Loop
Hopefully some of the above will be of use
I had the same question but applying the provided solutions changed the file to write in. Once I selected the new excel file, I was also writing in that file and not in my original file. My solution for this issue is below:
Sub GetData()
Dim excelapp As Application
Dim source As Workbook
Dim srcSH1 As Worksheet
Dim sh As Worksheet
Dim path As String
Dim nmr As Long
Dim i As Long
nmr = 20
Set excelapp = New Application
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Filters.Add "Excel Files", "*.xlsx; *.xlsm; *.xls; *.xlsb", 1
.Show
path = .SelectedItems.Item(1)
End With
Set source = excelapp.Workbooks.Open(path)
Set srcSH1 = source.Worksheets("Sheet1")
Set sh = Sheets("Sheet1")
For i = 1 To nmr
sh.Cells(i, "A").Value = srcSH1.Cells(i, "A").Value
Next i
End Sub
With excelapp a new application will be called. The with block sets the path for the external file. Finally, I set the external Workbook with source and srcSH1 as a Worksheet within the external sheet.
We have been using VBA code for years with Excel 2003. I have about 70 files that I pull information from and compile it into one spreadsheet. This time, it only recognizes 3 of the 70. I do not get any errors. I noticed that all 3 recognized are the old version ".xls." and all not being recognized are the ".xlsx". The portion of the code that I think is causing the problem is below. Can anyone help?
Public currApp As String
Public i As String
Public recordC As String
Public excelI As Integer
Public intFileHandle As Integer
Public strRETP As String
Public errFile As String
Public Function loopFiles(ByVal sFolder As String, ByVal noI As Integer)
'This function will loop through all files in the selected folder
'to make sure that they are all of excel type
Dim FOLDER, files, file, FSO As Object
excelI = noI
'MsgBox excelI
i = 0
'Dim writeFile As Object
'writeFile = My.Computer.FileSystem.WriteAllText("D:\Test\test.txt", "sdgdfgds", False)
Dim cnn As Connection
Set cnn = New ADODB.Connection
currApp = ActiveWorkbook.path
errFile = currApp & "\errorFile.txt"
If emptyFile.FileExists(errFile) Then
Kill errFile
Else
'Do Nothing
End If
'cnn.Open "DSN=AUTOLIV"
'cnn.Open "D:\Work\Projects\Autoliv\Tax workshop\Tax Schedules\sox_questionnaire.mdb"
cnn.Open ("DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & currApp & "\tax_questionnaire.mdb")
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
Set FSO = CreateObject("Scripting.FileSystemObject")
'Upon each found excel file it will make a call to saveFiles.
If sFolder <> "" Then
Set FOLDER = FSO.getfolder(sFolder)
Set files = FOLDER.files
For Each file In files
'ONLY WORK WITH EXCEL FILES
If file.Type = "Microsoft Excel Worksheet" Then
Workbooks.Open fileName:=file.path
xlsx is a "macro-free" workbook. To use VBA in the new file format, the file must be saved as an xlsm file.
EDIT: I read the question too hastily. If you want to identify excel files from the FSO object, use file.Type LIKE "Microsoft Excel *" or similar. Or, check the file's extension against ".xls*"
EDIT
The whole concept of identifying the file type by looking at the file name is fundamentally flawed. It's too easily broken by changes to file extensions and/or the "type" texts associated with those descriptions. It's easily broken by, say, an image file named "file.xls". I would just try opening the file with Workbooks.Open and catch the error. I'd probably put this logic in a separate function:
Function OpenWorkbook(strPath As String) As Workbook
On Error GoTo ErrorLabel
Set OpenWorkbook = Workbooks.Open(strPath)
ExitLabel:
Exit Function
ErrorLabel:
If Err.Number = 1004 Then
Resume ExitLabel
Else
'other error handling code here
Resume ExitLabel
End If
End Function
Then you can consume the function like this:
Dim w As Workbook
Set w = OpenWorkbook(file.Path)
If Not (w Is Nothing) Then
'...
The problem you're having has to do with this line:
If file.Type = "Microsoft Excel Worksheet" Then
Try adding and replacing it with this:
// add these lines just AFTER the line 'For Each file In files'
IsXLFile = False
FilePath = file.path
FilePath2 = Right(FilePath, 5)
FilePath3 = Mid(FilePath2, InStr(1, FilePath2, ".") + 1)
If UCase(Left(FilePath3, 2)) = "XL" Then IsXLFile = True
// replace faulty line with this line
If IsXLFile = True Then
Let me know how it works. Yes, it'd be possible to compress the statements that start with FilePath into one expression but I left it like that for clarity. Vote and accept the answer if good and follow-up if not.
Have a nice day.