I used the code that I found here.
After some changes this is the code I have now:
Option Explicit
Sub ExportAsCSV()
Dim MyFileName As String
Dim Item As String
Dim Path As String
Dim CurrentWB As Workbook, TempWB As Workbook
Path = "F:\Excels\csv export\"
Set CurrentWB = ActiveWorkbook
ActiveWorkbook.Worksheets("Nieuw Artikelnummer").UsedRange.Copy
Item = Range("D2")
Set CurrentWB = ActiveWorkbook
ActiveWorkbook.Worksheets("csv").UsedRange.Copy
Set TempWB = Application.Workbooks.Add(1)
With TempWB.Sheets(1).Range("A1")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
End With
MyFileName = Path & "\" & Item & ".csv"
Application.DisplayAlerts = False
TempWB.SaveAs filename:=MyFileName, FileFormat:=xlCSV, CreateBackup:=False, Local:=True
TempWB.Close SaveChanges:=False
Application.DisplayAlerts = True
MsgBox ".csv file has been created: " _
& vbCrLf _
& MyFileName
End Sub
The problem I have is that it uses the UsedRange, but I would like to select the Range that is copied into the new .csv file.
What can I do to select the Range to copy into the new file instead of the UsedRange?
This will open an input box on the article number sheet that allows you to hand select or type in a range:
Sub ExportAsCSV()
Dim MyFileName As String
Dim Item As String
Dim Path As String
Dim CurrentWB As Workbook, TempWB As Workbook
Dim myrangeNA As Range
Dim myRangeCSV As Range
Path = "F:\Excels\csv export\"
Set CurrentWB = ActiveWorkbook
ActiveWorkbook.Worksheets("Nieuw Artikelnummer").Activate
Set myrangeNA = Application.InputBox(prompt:="Select a range to copy", Type:=8)
Item = Range("D2")
Set TempWB = Application.Workbooks.Add(1)
myrangeNA.Copy Destination:=TempWB.Worksheets("Sheet1").Range("A1")
MyFileName = Path & "\" & Item & ".csv"
Application.DisplayAlerts = False
TempWB.SaveAs Filename:=MyFileName, FileFormat:=xlCSV, CreateBackup:=False, Local:=True
TempWB.Close SaveChanges:=False
Application.DisplayAlerts = True
MsgBox ".csv file has been created: " _
& vbCrLf _
& MyFileName
End Sub
If you don't want to select it, change the myrangeNA to whatever range you want, like range("A5:C20") and it should work.
For situations like this, I prefer to isolate the actions to a standalone Sub or Function that I can call with parameters. In this way I can reuse it as needed, either in this project or another one.
So I've separated the actions of copying the selected data range and pasting to a temporary workbook, then saving to a CSV file in it's own Function. The action returns a True/False result as a check for success.
Option Explicit
Sub test()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
Dim destCSVfile As String
destCSVfile = "C:\Temp\" & ws.Range("D2")
If ExportAsCSV(Selection, destCSVfile) Then
MsgBox ".csv file has been created: " _
& vbCrLf _
& destCSVfile
Else
MsgBox ".csv file NOT created"
End If
End Sub
Private Function ExportAsCSV(ByRef dataArea As Range, _
ByVal myFileName As String) As Boolean
'--- make sure we have a range to export...
ExportAsCSV = False
If dataArea Is Nothing Then
Exit Function
End If
dataArea.Copy
'--- create a temporary workbook that will be saved as a CSV format
Dim tempWB As Workbook
Set tempWB = Application.Workbooks.Add(1)
With tempWB.Sheets(1).Range("A1")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
End With
'--- suppress alerts to convert the temp book to CSV
Application.DisplayAlerts = False
tempWB.SaveAs filename:=myFileName, FileFormat:=xlCSV, _
CreateBackup:=False, Local:=True
tempWB.Close SaveChanges:=False
Application.DisplayAlerts = True
ExportAsCSV = True
End Function
Your other two questions in the comment above mention pasting transposed values, which you would do by changing the line myrangeNA.Copy Destination:=TempWB.Worksheets("Sheet1").Range("A1") to
myrangeNA.Copy
TempWB.Worksheets("Sheet1").Range("A1").PasteSpecial _
Paste:=xlPasteValues, Transpose:=True
This site is a great reference source for all the various objects and methods and properties in the Office VBA collection: https://learn.microsoft.com/en-us/office/vba/api/overview/excel/object-model
(or https://learn.microsoft.com/de-de/office/vba/api/overview/excel/object-model if you prefer to have about five words translated to German)
Related
This year I inherited support of about a dozen accdb applications in Office 2010 Win 7 that often manipulate external excel files.
I keep getting the same error scenario. It is in my vba for excel commands,
but only AFTER the first iteration of a loop. It always works fine the first time through. Seems to have something to do with how I am identifying the objects. I've read multiple articles on best practices for working with the objects and the specific error but nothing has translated into a solution. Can someone ELI5 what I am doing wrong?
In the example below it is throwing the error early in the second iteration at the Range("A1").Select command.
Code:
Sub runCleanAndImportUnpre()
Dim strFolder As String
Dim strTableDest As String
strTableDest = "Unpresented_EOD_Import"
strFolder = "C:\Users\lclambe\Projects\Inputs\test2"
Call CleanAndImportUnpresentedInAGivenFolder(strTableDest, strFolder)
End Sub
Function CleanAndImportUnpresentedInAGivenFolder(strTable As String, strFolder As String)
' Function that opens files in a folder, cleans them up and saves them.
Dim myfile
Dim mypath
Dim strPathFileName As String
Dim i As Integer
'Call ClearData(strTable)
'if it needs a backslash on the end, add one
If Right(strFolder, 1) <> "\" Then
strFolder = strFolder & "\"
End If
mypath = strFolder
ChDir (strFolder)
myfile = Dir(mypath)
ChDir (mypath)
myfile = Dir("")
i = 1
Do While myfile <> ""
'Format the excel report
strPathFileName = mypath & myfile
'use for unpresented
Call formatExcelUnPresentedForImport(strPathFileName)
i = i + 1
myfile = Dir()
Loop
End Function
Function formatExcelUnPresentedForImport(filePath As String)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Note:
' Called from CleanAndImportUnpresentedInAGivenFolder when
' importing Unpresented reports
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
On Error GoTo formatExcelUnPresentedForImport_Error
Dim strFilePath As String
Dim strReportType As String
Dim i As Integer
Dim iTotal_Row
Dim Lastrow As Long
Dim iCol As Integer
Dim appExcel As excel.Application
Dim wkb As excel.Workbook
Dim sht As Worksheet
Dim rng As Range
strReportType = reportType
strFilePath = filePath
Set appExcel = New excel.Application
appExcel.Visible = False
'Define the worksheet
Set wkb = appExcel.Workbooks.Open(strFilePath, ReadOnly:=False)
'Turn off error msg: "minor loss of fidelity" if you are sure no data will be lost
wkb.CheckCompatibility = False
'Expand Column to avoid scientific notation
appExcel.Columns("A:A").EntireColumn.AutoFit
'Find last row
'FAILS HERE ON SECOND ITERATION OF LOOP:
Range("A1").Select
ActiveCell("A1").Select
Selection.End(xlDown).Select
'Delete the last 3 rows of totals
ActiveCell.offset(-2, 0).Select
Selection.EntireRow.Delete
Selection.EntireRow.Delete
Selection.EntireRow.Delete
'Add a TRIM of Cash Amount Field2 at column L
Range("L2").Select
ActiveCell.FormulaR1C1 = "=TRIM(RC[-9])"
Range("L2").Select
'Copy it to rest of cells to bottom
Selection.Copy
Lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
Selection.AutoFill Destination:=Range("L2:L" & Lastrow), Type:=xlFillDefault
Range("L2:L" & Lastrow).Select
'Delete original unformatted unpresented
Selection.Copy
ActiveSheet.Paste
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Delete all the rows except Unpresented
Range("B:B,C:C,D:D,E:E,F:F,G:G,H:H,I:I,J:J,K:K").Select
Range("K1").Activate
Selection.Delete Shift:=xlToLeft
'Add a Header
Range("B1").Select
ActiveCell.FormulaR1C1 = "Unpresented"
wkb.Save
wkb.Close
appExcel.Quit
Set wkb = Nothing
Set appExcel = Nothing
On Error GoTo 0
Exit Function
formatExcelUnPresentedForImport_Error:
Set wkb = Nothing
Set appExcel = Nothing
strMessage = "Error " & err.Number & " (" & err.Description & ") in procedure formatExcelUnPresentedForImport of Module modExternalExcelClean."
strMessage = strMessage & " Application will stop processing now." & vbNewLine
strMessage = strMessage & "Please note or copy this error message and contact application developer for assistance."
MsgBox strMessage, vbCritical + vbOKOnly, "Error"
End
End Function
Just guessing that you are not iterating through an Excel file the second time, thus it throws an error. To debug it in ELI5 style, change your code like this:
Do While myfile <> ""
MsgBox myFile
'Format the excel report
strPathFileName = mypath & myfile
'use for unpresented
Call formatExcelUnPresentedForImport(strPathFileName)
i = i + 1
myfile = Dir()
Loop
and pay attention to the MsgBox every time. Is it showing what you think it should be showing?
I have a tab in excel that has about 50 columns. I export this tab as a .CSV file and upload it into a database. I am currently using this VBA code to export the .CSV file:
Sub ExportAsCSV()
Dim MyFileName As String
Dim CurrentWB As Workbook, TempWB As Workbook
Set CurrentWB = ActiveWorkbook
ActiveWorkbook.ActiveSheet.UsedRange.Copy
Set TempWB = Application.Workbooks.Add(1)
With TempWB.Sheets(1).Range("A1")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
End With
'Dim Change below to "- 4" to become compatible with .xls files
MyFileName = CurrentWB.Path & "\" & Left(CurrentWB.Name, Len(CurrentWB.Name) - 5) & ".csv"
Application.DisplayAlerts = False
TempWB.SaveAs Filename:=MyFileName, FileFormat:=xlCSV, CreateBackup:=False, Local:=True
TempWB.Close SaveChanges:=False
Application.DisplayAlerts = True
End Sub
There are certain columns in this export tab that will have "null" (actual word null) if the connected cells in other sheets are not filled in. How can I add to this existing VBA code to not allow an export if there are any null (the word, not blanks) values? Also how can a box pop up telling you that it wont export due to nulls?
I fixed your code's structure and added a test at the start which checks to make sure you have no "null" values anywhere on your ActiveSheet - if you do, it will throw a pop-up then exit the macro.
Sub ExportAsCSV()
If Application.WorksheetFunction.CountIf(ActiveSheet.UsedRange, "null") > 0 Then
MsgBox "Null values exist in the range - exiting sub.", vbExclamation
Exit Sub
End If
Dim MyFileName As String
Dim CurrentWB As Workbook, TempWB As Workbook
Set CurrentWB = ActiveWorkbook
ActiveWorkbook.ActiveSheet.UsedRange.Copy
Set TempWB = Application.Workbooks.Add(1)
With TempWB.Sheets(1).Range("A1")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
End With
'Dim Change below to "- 4" to become compatible with .xls files
MyFileName = CurrentWB.Path & "\" & Left(CurrentWB.Name, Len(CurrentWB.Name) - 5) & ".csv"
Application.DisplayAlerts = False
TempWB.SaveAs Filename:=MyFileName, FileFormat:=xlCSV, CreateBackup:=False, Local:=True
TempWB.Close SaveChanges:=False
Application.DisplayAlerts = True
End Sub
It's a lot more elaborate, but I think it's the right way to do it. Plus, it activates the first "null" cell for the end user to look at.
Add the following lines to the top of your code:
Sub ExportAsCSV()
Dim NullAddress As String
NullAddress = FindNull(ActiveSheet.UsedRange)
If NullAddress <> vbNullString Then
ActiveSheet.Range(NullAddress).Activate
MsgBox "Cannot Export due to ""null"" value in cell"
Exit Sub
End If
'
'
'
End Sub
which replies on the test function to do the heavy lifting:
Function FindNull(Target As Excel.Range) As String
Const NullValue As String = "null"
Dim vData 'As Variant
Dim Row As Long, Col As Long
If Not Target Is Nothing Then
vData = Target
If IsArray(vData) Then
For Row = 1 To Target.Rows.Count
For Col = 1 To Target.Columns.Count
If vData(Row, Col) = NullValue Then
' Return the Address of the first Null value found & Exit
FindNull = Target.Parent.Cells(Target.Cells(1).Row + Row - 1, Target.Cells(1).Column + Col - 1).Address(RowAbsolute:=False, ColumnAbsolute:=False)
Exit Function
End If
Next
Next
Else
If vData = NullValue Then FindNull = Target.Address
End If
End If
End Function
I could have sworn that this was working before - but for some reason, this doesn't appear to be working anymore. I'm trying to take the active worksheet (also, this may not be very pretty or clean, but I am still really new to VBA), copy it to a new worksheet, in the new worksheet I want to open the Excel save as dialog, and when the worksheet is saved (in CSV) format, I want the workbook to close (or even if it doesn't close) at least return the user to the original workbook and end the sub
Sub saveExportAs()
Application.CutCopyMode = False
Sheets("load").Select
ActiveWorkbook.Activate
Sheets("load").Copy
Dim varResult As Variant
Dim ActBook As Workbook
'display the save as dialog
varResult = Application.GetSaveAsFilename(InitialFileName:="\\network\folder\upload_" & Format(Date, "yyyy-mm-dd") & ".csv", FileFilter:= _
"Comma Delimited / Upload Files (*.csv),*.csv", Title:="Save Upload File")
'check to make sure the user didn't cancel
If varResult <> False Then
ActiveWorkbook.saveAs Filename:=varResult, _
FileFormat:=xlCSV
Exit Sub
End If
End Sub
you can use the sheets defined as workbook/worksheet to avoid issues... may be like this :
Sub saveExportAs()
Dim wb1, wb2 As Workbook
Dim ws As Worksheet
Dim varResult As Variant
Set wb1 = ThisWorkbook
Set ws = ThisWorkbook.Worksheets("load")
ws.Copy
Set wb2 = ActiveWorkbook
varResult = Application.GetSaveAsFilename(InitialFileName:="\\network\folder\upload_" & Format(Date, "yyyy-mm-dd") & ".csv", FileFilter:= _
"Comma Delimited / Upload Files (*.csv),*.csv", Title:="Save Upload File")
If varResult <> False Then
wb2.SaveAs Filename:=varResult, FileFormat:=xlCSV
wb2.Close Savechanges:=True
Exit Sub
End If
wb1.Activate
End Sub
Try this...
Sub exportAsCSV()
Dim wb As Workbook
Set wb = ActiveWorkbook
SaveCopyAsCSV ("Sheet1") ' replace Sheet1 with whatever sheet name you need
wb.Activate
End Sub
Private Function SaveCopyAsCSV(SourceSheet As String)
Application.DisplayAlerts = False
ThisWorkbook.Sheets(SourceSheet).copy
ActiveWorkbook.SaveAs fileName:=SourceSheet, FileFormat:=xlCSV, CreateBackup:=True
ActiveWorkbook.Close
Application.DisplayAlerts = True
End Function
I have a folder with nearly 1000 .csv files. Each of these files contains 2 columns, and I would like to copy only one of these columns and transpose it onto a new workbook. The new workbook will contain all the data from each of these files. The following code is what I have generated:
Sub AllFiles()
Application.EnableCancelKey = xlDisabled
Dim folderPath As String
Dim Filename As String
Dim wb As Workbook
folderPath = "J:etc. etc. etc." 'contains folder path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
Filename = Dir(folderPath & "*.csv")
Do While Filename <> ""
Application.ScreenUpdating = False
Set wb = Workbooks.Open(folderPath & Filename)
wb.Range(Range("B1"), Range("B1").End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
ActiveWorkbook.Close True
Windows("Compiled.xlsm").Activate
Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Transpose:=True
Filename = Dir
Loop
Application.ScreenUpdating = True
End Sub
For whatever reason the code does not work and a box pops-up saying "Code execution has been interrupted." Once I hit "Debug" the following line is highlighted:
wb.Range(Range("B1"), Range("B1").End(xlDown)).Select
I am not experienced with VBA at all and I am having trouble troubleshooting this issue. Any idea on what this means and what I can do?
The highlighted line is referring to a range on the workbook that is running the macro as opposed to the range within the workbook you have opened. Try replacing with this:
wb.Range(wb.Range("B1"), wb.Range("B1").End(xlDown)).Select
However I would suggest you avoid using the Select function altogether as it tends to slow down code. I've trimmed the loop a bit to avoid using Select and Activate:
Do While Filename <> ""
Application.ScreenUpdating = False
Set wb = Workbooks.Open(folderPath & Filename)
wb.Range(wb.Cells(1,"B"), wb.Cells(Rows.Count,"B").End(xlUp)).Copy
Workbooks("Compiled.xlsm").Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Transpose:=True
wb.Close True
Filename = Dir
Loop
Once you open file file, the active workbook is the book just opened and the active sheet is also established.
Your code fails primarily because of the wb.. (In general you would use a sheet reference instead), but in this case, replace:
wb.Range(Range("B1"), Range("B1").End(xlDown)).Select
with:
Range("B1").End(xlDown)).Select
(You also do not need Select to accomplish a copy/paste)
try with below
Sub AllFiles()
Application.EnableCancelKey = xlDisabled
Dim folderPath As String
Dim Filename As String
Dim wb As Workbook
folderPath = "c:\work\test\" 'contains folder path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
Filename = Dir(folderPath & "*.xlsx")
Do While Filename <> ""
Application.ScreenUpdating = False
Set wb = Workbooks.Open(folderPath & Filename)
Range("B1:B" & Range("B" & Rows.count).End(xlUp).Row).Copy
Workbooks("Compiled").Worksheets("Sheet1").Range("A" & Range("A" & Rows.count).End(xlUp).Row + 1).PasteSpecial Transpose:=True
Workbooks(Filename).Close True
Filename = Dir
Loop
Application.ScreenUpdating = True
End Sub
wb.Range(...) will never work since wb is a Workbook object. You need a Worksheet object. Try:
Dim ws As Worksheet
Set ws = wb.Activesheet
ws.Range(ws.Range("B1"), ws.Range("B1").End(xlDown)).Select
Hi I was wondering if anybody could help me, I have (below) code in a module, however, if I am currently in a different open workbook an error message pops up. I am guessing it is trying to execute the macro in the current selected workbook instead of the needed workbook ("MKL").
Below is the code.
Dim TimeToRun
Sub auto_open()
Call ScheduleCopyPriceOver
End Sub
Sub ScheduleCopyPriceOver()
TimeToRun = Now + TimeValue("00:01:00")
Application.OnTime TimeToRun, "CopyPriceOver"
End Sub
Sub CopyPriceOver()
Application.DisplayAlerts = False
Dim MyPath As String
Dim MyFileName As String
Dim celltxt As String
Calculate
Workbooks("MKL.xlsm").Sheets("Data Quarter Hourly").Select
Call ScheduleCopyPriceOver
Workbooks("MKL.xlsm").Sheets("Data Quarter Hourly").Rows("9:9").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Workbooks("MKL.xlsm").Sheets("Data Quarter Hourly").Range("DateNow:Stock2").Copy
Workbooks("MKL.xlsm").Sheets("Data Quarter Hourly").Range("A9:C9").PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Range("D10:CB10").Copy
Workbooks("MKL.xlsm").Sheets("Data Quarter Hourly").Range("D9:CB9").PasteSpecial Paste:=xlFormulas, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
celltxt = Workbooks("MKL.xlsm").Sheets("Trades").Range("C2").Text
If InStr(1, celltxt, "A") Or InStr(1, celltxt, "B") Then
MyPath = "Z:\capital\Research - internal\Arb Trading Models\Trades"
MyFileName = "Trades " & Format(Now(), "dd-mmm-yyyy hh-mm-ss")
If Not Right(MyPath, 1) = "\" Then MyPath = MyPath & "\"
If Not Right(MyFileName, 4) = ".xls" Then MyFileName = MyFileName & ".xls"
Workbooks("MKL.xlsm").Sheets("Trades").Copy
With ActiveWorkbook
.SaveAs Filename:= _
MyPath & MyFileName, _
Local:=True, _
FileFormat:=xlWorkbookNormal, _
CreateBackup:=False
.Close False
End With
End If
Application.DisplayAlerts = True
End Sub
Sub auto_close()
On Error Resume Next
Application.OnTime TimeToRun, "CopyPriceOver", , False
End Sub
Any help will be very much appreciated.
I noticed a few things that could throw off your code due to implicit references.
I went through the CopyPriceOver and replaced the implicit reference with a more explicit one, useda worksheet and workbbok objects and added a few comments:
Sub CopyPriceOver()
Application.DisplayAlerts = False
Dim MyPath As String
Dim MyFileName As String
Dim celltxt As String
Dim wb As Workbook: Set wb = Workbooks("MKL.xlsm") '<~~ we set a workbook object wb to the workbook "MKL.xlsm", this will save us a lot of writin and improve readability
Dim wsDataQuarterHourly As Worksheet: Set wsDataQuarterHourly = wb.Worksheets("Data Quarter Hourly") '<~~ set a worksheet object to reference the "Data Quarter Hourly" sheet in the MKL.xlsm workbook, by use of the above wb object
Dim wsTrades As Worksheet: Set wsTrades = wb.Worksheets("Trades") '<~~ set a worksheet object to reference the "Trades" sheet in in the MKL.xlsm workbook
Calculate
wsDataQuarterHourly.Select '<~~ i don't see the need to select it? I may be completely wrong, but if omitted what happens to your execution?
Call ScheduleCopyPriceOver
wsDataQuarterHourly.Rows("9:9").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove '<~~ using the worksheet object
wsDataQuarterHourly.Range("DateNow:Stock2").Copy '<~~ I was not aware you could reference ranges like that? and it not working on my end
wsDataQuarterHourly.Range("A9:C9").PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
'Next line should be updated
Range("D10:CB10").Copy '<~~ what do you want to copy? if from the "Data Quarter Hourly" then wsDataQuarterHourly.Range("D10:CB10")
wsDataQuarterHourly.Range("D9:CB9").PasteSpecial Paste:=xlFormulas, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
celltxt = wsTrades.Range("C2").Text
If InStr(1, celltxt, "A") Or InStr(1, celltxt, "B") Then
MyPath = "Z:\capital\Research - internal\Arb Trading Models\Trades"
MyFileName = "Trades " & Format(Now(), "dd-mmm-yyyy hh-mm-ss")
If Not Right(MyPath, 1) = "\" Then MyPath = MyPath & "\"
If Not Right(MyFileName, 4) = ".xls" Then MyFileName = MyFileName & ".xls"
wsTrades.Copy '<~~ why copy? I don't see it used?
With wb '<~~ explicit reference to the "MKL.xlsm" workbook
.SaveAs Filename:= _
MyPath & MyFileName, _
Local:=True, _
FileFormat:=xlWorkbookNormal, _
CreateBackup:=False
.Close False
End With
End If
Application.DisplayAlerts = True
End Sub
in the code above, and in your own, You should pay special attention to the line:
Range("D10:CB10").Copy
It implicitly implies the range D10:CB10 in the ActiveSheet of the ActiveWorkbook. If you working in a different workbook, it would reference D10:CB10 in what ever sheet is active in that WorkBook. While that may not cause an error I doubt it was intended.
Also, when you save the Workbook you referenced the ActiveWorkbook, which again would be the one you are working in.
I had some issues with a line that copies a *.Range("DateNow:Stock2"), that I have no idea what should be why I have not properly tested the code
Presumably 'ScheduleCopyPriceOver' is defined in a module in Workbook 'MKL.xlsm'?
Try using Workbooks("MKL.xlsm").Sheets("Data Quarter Hourly").Activate and putting the Sub 'ScheduleCopyPriceOver' into the "MKL.xlsm", ThisWorkbook module in the 'Sub Workbook_Activate()' event.
Don't forget to comment-out the existing Call in Sub CopyPriceOver()