VBA / Macro upgraded from 32 bit to 64 bit - excel

I have been upgraded from 32bit to 64 bit and my macro to merge and arrange files in a folder does not work any more, not a VBA user so am pretty much stuck and would appreciate help getting the marco to work ?
Option Explicit
'32-bit API declarations
Declare Function SHGetPathFromIDList Lib "shell32.dll" _
Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal _
pszpath As String) As Long
Declare Function SHBrowseForFolder Lib "shell32.dll" _
Alias "SHBrowseForFolderA" (lpBrowseInfo As BrowseInfo) _
As Long
Public Type BrowseInfo
hOwner As Long
pIDLRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
Function GetDirectory(Optional msg) As String
On Error Resume Next
Dim bInfo As BrowseInfo
Dim path As String
Dim r As Long, x As Long, pos As Integer
'Root folder = Desktop
bInfo.pIDLRoot = 0&
'Title in the dialog
If IsMissing(msg) Then
bInfo.lpszTitle = "Please select the folder of the excel files to copy."
Else
bInfo.lpszTitle = msg
End If
'Type of directory to return
bInfo.ulFlags = &H1
'Display the dialog
x = SHBrowseForFolder(bInfo)
'Parse the result
path = Space$(512)
r = SHGetPathFromIDList(ByVal x, ByVal path)
If r Then
pos = InStr(path, Chr$(0))
GetDirectory = Left(path, pos - 1)
Else
GetDirectory = ""
End If
End Function
Sub CombineFiles()
Dim path As String
Dim FileName As String
Dim LastCell As Range
Dim Wkb As Workbook
Dim ws As Worksheet
Dim ThisWB As String
Application.DisplayAlerts = False
ThisWB = ThisWorkbook.Name
Application.EnableEvents = False
Application.ScreenUpdating = False
path = GetDirectory
FileName = Dir(path & "\*.xlsx", vbNormal)
Do Until FileName = ""
If FileName <> ThisWB Then
Set Wkb = Workbooks.Open(FileName:=path & "\" & FileName)
For Each ws In Wkb.Worksheets
If ws.Visible = xlSheetHidden Then
Else
ws.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
End If
Next ws
Wkb.Close False
End If
FileName = Dir()
Loop
Application.EnableEvents = True
Application.ScreenUpdating = True
Set Wkb = Nothing
Set LastCell = Nothing
Call Sort_Tabs
Call Hide_create_tab
Call Select_all_sheets
Application.Dialogs(xlDialogSaveAs).Show "Enter MCR file name"
Application.DisplayAlerts = True
End Sub
Sub Sort_Tabs()
'declare our variables
Dim i, j As Integer
Dim iNumSheets As Integer
'find the number of sheets to work with
iNumSheets = ActiveWorkbook.Sheets.Count
'turn off screen updating to prevent screen flicker
Application.ScreenUpdating = False
'work through our number of sheets
For i = 1 To iNumSheets - 1
For j = i + 1 To iNumSheets
'check the name of the sheet regardless of case
If UCase(Sheets(i).Name) > UCase(Sheets(j).Name) Then
'set where to move the sheet to
Sheets(j).Move before:=Sheets(i)
End If
'do next sheet
Next j
Next i
'let the screen update
Application.ScreenUpdating = True
End Sub
Sub Hide_create_tab()
Sheets("Create MCR").Select
ActiveSheet.Visible = False
End Sub
Sub Select_all_sheets()
Dim ws As Worksheet
For Each ws In Sheets
If ws.Visible Then ws.Select (False)
Next
End Sub

Have a look at this page:
https://jkp-ads.com/Articles/apideclarations.asp
NB: Please make sure all code in your message is marked as such so we can easily read the code.

Related

VBA match function mismatch despite having the search value in source

Option Explicit
Sub ExtractDivFromAastocks()
Dim StockCode As String, Anchor As String
Dim ws As Worksheet
StockCode = "02800"
Anchor = "Announce Date"
Set ws = ExtractRawDivFromAastocks(StockCode)
Call CleanAastocksDiv(StockCode, ws)
End Sub
Private Function ExtractRawDivFromAastocks(StockCode As String)
Dim WsFound As Boolean
Dim i As Integer
WsFound = False
For i = 1 To Sheets.Count():
If Worksheets(i).Name = StockCode Then
WsFound = True
End If
If WsFound = True Then
Exit For
End If
Next i
If WsFound = True Then
Application.DisplayAlerts = False
Worksheets(StockCode).Delete
Application.DisplayAlerts = True
End If
Dim ws As Worksheet
Dim qt As QueryTable
Dim Website As String, Aastock As String
Aastock = "http://www.aastocks.com/en/stocks/analysis/dividend.aspx?symbol="
Website = Aastock & StockCode
Set ws = Sheets.Add(After:=Worksheets(Worksheets.Count()))
ws.Name = StockCode
Set qt = ws.QueryTables.Add( _
Connection:="URL;" & Website, _
Destination:=ws.Range("A1"))
With qt
.RefreshOnFileOpen = True
.Refresh
End With
Set ExtractRawDivFromAastocks = ws
End Function
Private Sub CleanAastocksDiv(StockCode As String, ws As Worksheet)
Dim StartRow As Integer
StartRow = Application.Match("Announce Date", ws.Range("A:A"), 0)
ws.Range("A1:" & _
ws.Cells(StartRow - 1, ws.Columns.Count()).Address).EntireRow.Delete
End Sub
The worksheet indeed has the string value in it, and I have no idea why the match fails. I have tried using the Match function on the sheet itself, it works. Could this be some kind of reference issues? The cell in the sheet doesn't seem to have weird whitespaces. It would be really great if anyone can help me with this:
Public Sub TestMe()
Dim ws As Worksheet: Set ws = Worksheets(1)
Dim StartRow As Variant
StartRow = Application.Match("Announce Date", ws.Range("A:A"), 0)
If IsError(StartRow) Then Exit Sub
If StartRow < 2 Then Exit Sub
ws.Range("A1:A" & StartRow - 1).EntireRow.Delete
End Sub
Declare StartRow as a Variant, because if Announce Date does not exist, it would return an error;
It can be checked with the IsError(StartRow) and exit if it is not the case;
If StartRow < 2 Exit Sub is needed to avoid a possible error if StartRow is 1;

Merging Multiple Workbooks into Single Sheet

I'm trying to merge multiple Excel workbooks into a single sheet.
I found code to choose the folder and merge all the Excel files in the folder into current active workbook.
The target workbook consists of two sheets which is PID and Services.
Option Explicit
Public strPath As String
Public Type SELECTINFO
hOwner As Long
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal pszPath As String) As Long
Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" (lpBrowseInfo As SELECTINFO) As Long
Function SelectFolder(Optional Msg) As String
Dim sInfo As SELECTINFO
Dim path As String
Dim r As Long, x As Long, pos As Integer
sInfo.pidlRoot = 0&
If IsMissing(Msg) Then
sInfo.lpszTitle = "Select your folder."
Else
sInfo.lpszTitle = Msg
End If
sInfo.ulFlags = &H1
x = SHBrowseForFolder(sInfo)
path = Space$(512)
r = SHGetPathFromIDList(ByVal x, ByVal path)
If r Then
pos = InStr(path, Chr$(0))
SelectFolder = Left(path, pos - 1)
Else
SelectFolder = ""
End If
End Function
' "Merging Part"
Sub MergeExcels()
Dim path As String, ThisWB As String, lngFilecounter As Long
Dim wbDest As Workbook, shtDest As Worksheet, ws As Worksheet
Dim Filename As String, Wkb As Workbook
Dim CopyRng As Range, Dest As Range
Dim RowofCopySheet As Integer
RowofCopySheet = 1
ThisWB = ActiveWorkbook.Name
path = SelectFolder("Select a folder containing Excel files you want to merge")
Application.EnableEvents = False
Application.ScreenUpdating = False
Set shtDest = ActiveWorkbook.Sheets(1)
Filename = Dir(path & "\*.xls", vbNormal)
If Len(Filename) = 0 Then Exit Sub
Do Until Filename = vbNullString
If Not Filename = ThisWB Then
Set Wkb = Workbooks.Open(Filename:=path & "\" & Filename)
Set CopyRng = Wkb.Sheets(1).Range(Cells(RowofCopySheet, 1), Cells(ActiveSheet.UsedRange.Rows.Count, ActiveSheet.UsedRange.Columns.Count))
Set Dest = shtDest.Range("A" & shtDest.UsedRange.SpecialCells(xlCellTypeLastCell).Row + 1)
CopyRng.Copy Dest
Wkb.Close False
End If
Filename = Dir()
Loop
Range("A1").Select
Application.EnableEvents = True
Application.ScreenUpdating = True
MsgBox "Files Merged!"
End Sub
I need to copy Sheet1 (PID) and Sheet2 (Services). The code merges sheet1 (PID) only.
I tried to tweak the code.
Set shtDest = ActiveWorkbook.Sheets(1)
Filename = Dir(path & "\*.xls", vbNormal)
If Len(Filename) = 0 Then Exit Sub
Do Until Filename = vbNullString
If Not Filename = ThisWB Then
Set Wkb = Workbooks.Open(Filename:=path & "\" & Filename)
Set CopyRng = Wkb.Sheets(1).Range(Cells(RowofCopySheet, 1), Cells(ActiveSheet.UsedRange.Rows.Count, ActiveSheet.UsedRange.Columns.Count))
Set Dest = shtDest.Range("A" & shtDest.UsedRange.SpecialCells(xlCellTypeLastCell).Row + 1)
CopyRng.Copy Dest
Wkb.Close False
End If
I tried to change
ActiveWorkbook.Sheets(1) to ActiveWorkbook.Sheets(2) and
Set CopyRng = Wkb.Sheets(1) to Set CopyRng = Wkb.Sheets(2).
after tweaking and testing the code, i managed to find the way. The solution is just add "Wkb.Sheets(2).Activate" and the change Set CopyRng = Wkb.Sheets(1) to Set CopyRng = Wkb.Sheets(2) to merge the second sheet. Below are the sample code.
Set shtDest = ActiveWorkbook.Sheets(1)
Filename = Dir(path & "\*.xls", vbNormal)
If Len(Filename) = 0 Then Exit Sub
Do Until Filename = vbNullString
If Not Filename = ThisWB Then
Set Wkb = Workbooks.Open(Filename:=path & "\" & Filename)
Wkb.Sheets(2).Activate
Set CopyRng = Wkb.Sheets(2).Range(Cells(RowofCopySheet, 1), Cells(ActiveSheet.UsedRange.Rows.Count, ActiveSheet.UsedRange.Columns.Count))
Set Dest = shtDest.Range("A" & shtDest.UsedRange.SpecialCells(xlCellTypeLastCell).Row)
CopyRng.Copy Dest
Wkb.Close False
End If

call function unintentionally excel vba

I have the following sub that has worked for months:
Sub copy_over_csv_files()
Application.ScreenUpdating = False
Dim wbName As String: wbName = ThisWorkbook.Name
Dim totalSheets As Integer:
Dim filePath As String ' used to hold file path for finding the needed csv file
Dim fileName As String
Dim fileNameArray() As Variant
ReDim fileNameArray(9)
fileNameArray = Array("x.csv", _
"y.csv", "z.csv", _
"n.csv", "q.csv", _
"r.csv", "s.csv", _
"a.csv", "b.csv", "c.csv")
Dim n As Integer ' counter for file names array loop
For n = 0 To 9
totalSheets = Workbooks(wbName).Sheets.Count
filePath = "Macintosh HD:Users:file1:file2:file3:" & fileNameArray(n)
ChDir "Macintosh HD:Users:file1:file2:file3:"
Workbooks.Open fileName:=filePath ' file path to needed file
Sheets(fileNameArray(n)).Select
Sheets(fileNameArray(n)).Copy After:=Workbooks(wbName).Sheets(totalSheets)
Windows(fileNameArray(n)).Activate
ActiveWorkbook.Close
ActiveWorkbook.Save
Next n
Application.ScreenUpdating = True
End Sub
Then I wrote the following function:
Function GetAgentEmailWorksheet(AgentObjectId As String)
Dim specific_agent As clsAgent
Set specific_agent = New clsAgent
specific_agent.AgentSheetName = "agentsFullOutput.csv"
Dim id_array() As Variant
id_array = specific_agent.AgentIDArray
Dim email_array() As Variant
email_array = specific_agent.AgentEmailArray
GetAgentEmailWorksheet = vlook_using_array(AgentObjectId, id_array, email_array)
End Function
For some reason, the following line in the first sub: Sheets(fileNameArray(n)).Copy After:=Workbooks(wbName).Sheets(totalSheets)
opens the function.
I don't know why and I don't know how to make it stop.

Keep record of people who open Excel file

The code below does exactly what I want.. It keeps a record of people that opens my excel file but the problem is that it keeps the file open to everyone.
I want this tab to work in the background, so it is not visible to anyone except for me, when I go to the backend or click a button somewhere that will make it visible.
Please not that just the case the tab Audit is visible, the code must always check if the tab is opened and hide immediately when someone opens the file
Thanks in advance
Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" ( _
ByVal lpBuffer As String, _
nSize As Long) As Long
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" ( _
ByVal lpBuffer As String, _
nSize As Long) As Long
Private pAuditSheet As Worksheet
Private Const USERNAME_COL = 1
Private Const COMPUTERNAME_COL = 2
Private Const OPEN_TIME_COL = 3
Private Const CLOSE_TIME_COL = 4
Private Const OPEN_WB_NAME_COL = 5
Private Const CLOSE_WB_NAME_COL = 6
Private Const KEEP_ONLY_LAST_N_ENTRIES = 1
Private Sub Workbook_Open()
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Workbook_Open
' Runs when the workbook is opened.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Me.Worksheets("Audit").Protect UserInterfaceOnly:=True
Dim WS As Worksheet
Dim RowNum As Long
Dim N As Long
Dim S As String
Application.ScreenUpdating = False
On Error Resume Next
Err.Clear
Set WS = Me.Worksheets("Audit")
If Err.Number = 9 Then
Set WS = Me.Worksheets.Add(before:=1)
WS.Name = "Audit"
End If
On Error GoTo 0
With WS
If .Cells(1, USERNAME_COL).Value = vbNullString Then
.Cells(1, USERNAME_COL).Value = "User Name"
.Cells(1, COMPUTERNAME_COL).Value = "Computer Name"
.Cells(1, OPEN_TIME_COL).Value = "Open Time"
.Cells(1, CLOSE_TIME_COL).Value = "Close Time"
.Cells(1, OPEN_WB_NAME_COL).Value = "Open WB Name"
.Cells(1, CLOSE_WB_NAME_COL).Value = "Close WB Name"
End If
'.Visible = xlSheetVeryHidden
RowNum = .Cells(.Rows.Count, USERNAME_COL).End(xlUp)(2, 1).Row
N = 255
S = String(N, vbNullChar)
N = GetUserName(S, N)
.Cells(RowNum, USERNAME_COL).Value = TrimToNull(S)
N = 255
S = String(N, vbNullChar)
N = GetComputerName(S, N)
.Cells(RowNum, COMPUTERNAME_COL).Value = TrimToNull(S)
.Cells(RowNum, OPEN_TIME_COL).Value = Now
' Leave Close Time empty. It will be filled on close.
.Cells(RowNum, CLOSE_TIME_COL).Value = vbNullString
.Cells(RowNum, OPEN_WB_NAME_COL).Value = ThisWorkbook.FullName
' Leave Close Name empty. It will be filled on close.
.Cells(RowNum, CLOSE_WB_NAME_COL).Value = vbNullString
.UsedRange.Columns.AutoFit
End With
Application.ScreenUpdating = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Workbook_BeforeClose
' Runs when the workbook is closed.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim WS As Worksheet
Dim RowNum As Long
Dim EndRow As Long
Dim LastDel As Long
Dim FirstDel As Long
Application.ScreenUpdating = False
Set WS = Worksheets("Audit")
With WS
RowNum = .Cells(.Rows.Count, CLOSE_TIME_COL).End(xlUp).Row + 1
.Cells(RowNum, CLOSE_TIME_COL).Value = Now
.Cells(RowNum, CLOSE_WB_NAME_COL).Value = ThisWorkbook.FullName
.UsedRange.Columns.AutoFit
If KEEP_ONLY_LAST_N_ENTRIES > 0 Then
EndRow = .Cells(.Rows.Count, USERNAME_COL).End(xlUp).Row
If EndRow > 2 Then
FirstDel = 2
LastDel = EndRow - KEEP_ONLY_LAST_N_ENTRIES
If LastDel > 2 Then
.Cells(FirstDel, "A").Resize(LastDel - 1, 1).Select
End If
End If
End If
End With
Application.ScreenUpdating = True
End Sub
Private Function TrimToNull(S As String) As String
'''''''''''''''''''''''''''''''''''''''''''''''''''
' TrimToNull
' Returns the portion of string S that is to the
' left of the vbNullChar, Chr(0).
'''''''''''''''''''''''''''''''''''''''''''''''''''
Dim N As Long
N = InStr(1, S, vbNullChar)
If N = 0 Then
TrimToNull = S
Else
TrimToNull = Left(S, N - 1)
End If
End Function
you may find that if you uncomment the line
.Visible = xlSheetVeryHidden
it will most probably work in the way you want it to!

Importing worksheets into one excel workbook

I have a folder with 111 excel work books. I want to copy and paste every file into one excel file into separate sheets. So one sheet should have the contents of one file. Each file contains only one sheet. Any ideas would help as i am not very familiar with VBA. And I don't want to copy and paste 111 times.
Thanks.
I had the same issue recently. This code is all you need. Specify a folder and it will combine all workbooks into one (handles them even if they have multiple sheets, too).
' found at: http://www.vbaexpress.com/kb/getarticle.php?kb_id=829
Option Explicit
'32-bit API declarations
Declare Function SHGetPathFromIDList Lib "shell32.dll" _
Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal _
pszpath As String) As Long
Declare Function SHBrowseForFolder Lib "shell32.dll" _
Alias "SHBrowseForFolderA" (lpBrowseInfo As BrowseInfo) _
As Long
Public Type BrowseInfo
hOwner As Long
pIDLRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
Function GetDirectory(Optional msg) As String
On Error Resume Next
Dim bInfo As BrowseInfo
Dim path As String
Dim r As Long, x As Long, pos As Integer
'Root folder = Desktop
bInfo.pIDLRoot = 0&
'Title in the dialog
If IsMissing(msg) Then
bInfo.lpszTitle = "Please select the folder of the excel files to copy."
Else
bInfo.lpszTitle = msg
End If
'Type of directory to return
bInfo.ulFlags = &H1
'Display the dialog
x = SHBrowseForFolder(bInfo)
'Parse the result
path = Space$(512)
r = SHGetPathFromIDList(ByVal x, ByVal path)
If r Then
pos = InStr(path, Chr$(0))
GetDirectory = Left(path, pos - 1)
Else
GetDirectory = ""
End If
End Function
Sub CombineFiles()
Dim path As String
Dim FileName As String
Dim LastCell As range
Dim Wkb As Workbook
Dim ws As Worksheet
Dim ThisWB As String
ThisWB = ThisWorkbook.Name
Application.EnableEvents = False
Application.ScreenUpdating = False
path = GetDirectory
FileName = Dir(path & "\*.xls", vbNormal)
Do Until FileName = ""
If FileName <> ThisWB Then
Set Wkb = Workbooks.Open(FileName:=path & "\" & FileName)
For Each ws In Wkb.Worksheets
Set LastCell = ws.cells.SpecialCells(xlCellTypeLastCell)
If LastCell.Value = "" And LastCell.Address = range("$A$1").Address Then
Else
ws.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.count)
End If
Next ws
Wkb.Close False
End If
FileName = Dir()
Loop
Application.EnableEvents = True
Application.ScreenUpdating = True
Set Wkb = Nothing
Set LastCell = Nothing
End Sub
This is a shorter version. You'll need to do Tools/References and add Microsoft Scripting Runtime.
Sub CopySheet1s()
' Copies first sheet from all workbooks in current path
' to a new workbook called wbOutput.xlsx
Dim fso As New Scripting.FileSystemObject
Dim vFile As Variant, sFile As String, lPos As Long
Dim wbInput As Workbook, wbOutput As Workbook
Dim fFolder As Folder
Const cOUTPUT As String = "wbOutput.xlsx"
If fso.FileExists(cOUTPUT) Then
fso.DeleteFile cOUTPUT
End If
Set wbOutput = Workbooks.Add()
Set fFolder = fso.GetFolder(ThisWorkbook.Path)
For Each vFile In fFolder.Files
lPos = InStrRev(vFile, "\")
sFile = Mid(vFile, lPos + 1)
If sFile <> cOUTPUT And sFile <> ThisWorkbook.Name And Left(sFile, 1) <> "~" Then
Set wbInput = Workbooks.Open(Filename:=sFile, ReadOnly:=True)
wbInput.Worksheets(1).Copy after:=wbOutput.Worksheets(1)
wbInput.Close savechanges:=False
End If
Next
wbOutput.SaveAs Filename:=cOUTPUT
wbOutput.Close
End Sub
Place all your .xls files into one folder, enter the files path in 'Enter Files Path Here' and run the macro.
Sub GetSheets()
Path = "C:\Enter Files Path Here\"
Filename = Dir(Path & "*.xls")
Do While Filename <> ""
Workbooks.Open Filename:=Path & Filename, ReadOnly:=True
For Each Sheet In ActiveWorkbook.Sheets
Sheet.Copy After:=ThisWorkbook.Sheets(1)
Next Sheet
Workbooks(Filename).Close
Filename = Dir()
Loop
End Sub

Resources