1

I have a small big problem with a very simple thing to do (apparently) in VBA. I have two workbooks. The first one is a tracker, saved on my computer. The second one is a file I receive daily, which I never save. This second excel file can have different names, therefore I cannot have a name in my code. I need to copy a range of cells from the second excel to my tracker. This is what I have and doesn't work (nothing happens when I action the command button):

  Sub OpenClose_Click()
    Dim i As Long
    Dim Filename As String
    Dim CellRange As String
    Dim wbkCur As Workbook
    Dim wbkNew As Workbook
    Set wbkCur = Workbooks("tracker")

        Filename = "C:\Users\tracker.xlsm"
        Set wbkNew = Workbooks.Open(Filename:=Filename)

        wbkNew.Worksheets("Info").Range("D8").Value=wbkCur.Worksheets("Data").Range("A2").Value 
        wbkNew.Close SaveChanges:=True

End Sub
Alexandra
  • 23
  • 3
  • you are copying from wbkNew to wbkCur – jsotola Aug 23 '17 at 19:53
  • What is the name of the workbook with your code? Is it "tracker"? or something else? Is the workbook with your code wbkCur or wbkNew? You are setting 2 workbooks to the name "tracker", wbkCur and wbkNew. Is that what you want? If so, it's a confusing way to do things. – Tony M Aug 23 '17 at 19:54
  • yes, the code is stored in "tracker", aka wbkCur. I do not know how to write the code for the other one. – Alexandra Aug 23 '17 at 20:01

2 Answers2

0

The easiest thing is probably going to be using a file picker from FileDialog, especially if your second workbook is not consistent.

Sub OpenClose_Click()

'Create a variable to hold the path
Dim wbkNewPath As String

'Select the file
MsgBox ("Please choose location of file to be imported:")

With Application.FileDialog(msoFileDialogOpen)
    .Show
        If .SelectedItems.Count = 1 Then
        wbkNewPath = .SelectedItems(1)
    End If
End With

'Cancel will return vbNullString, so end the procedure
If wbkNewPath = vbNullString Then End

'New workbook variables
Dim wbkNew As Workbook
Set wbkNew = Workbooks.Open(wbkNewPath)
Dim wbkNewInfo As Worksheet
Set wbkNewInfo = wbkNew.Sheets("Info")

'Create variables for current workbook
Dim wbkCur As Workbook
Set wbkCur = ThisWorkbook
Dim wbkCurData as worksheet
Set wbkCurData = wbkCur.Sheets("Data")

'Copy Data
wbkNewInfo.Range("D8").Value = wbkCurData.Range("A2").Value 
wbkNew.Close SaveChanges:=True

End Sub
BobtimusPrime
  • 174
  • 13
  • Thanks Bobtimus! Sadly i get a syntax error with this line : Set wbkCur as ThisWorkbook. Also, when i run the code, i get a "file open" window . – Alexandra Aug 23 '17 at 20:29
  • @Alexandra Sorry, the "Set" action requires a "=" operator. I've updated it. With the File Open window, I think this will be the easiest way to reference a file that will never be in the same place nor have the same name. You can have some place on your computer that you designate to save the file and overwrite it each day that you receive it. If this isn't satisfactory, you will need to add some more information regarding where you get the second file from. – BobtimusPrime Aug 23 '17 at 20:35
  • I get that second file from my e-mail, i just open it and copy the information i needed (from 8-10 different cells). I get the same type of e-mail maybe 10 times a day (from here my despair :) ) – Alexandra Aug 23 '17 at 20:51
  • Automating the opening of a spreadsheet from your email is a little more complex, though possible, particularly with Outlook. See [this answer](https://stackoverflow.com/questions/11781320/download-attachment-from-outlook-and-open-in-excel) from Siddharth Rout for a tutorial. I think you'll find if you just right-click and "Save As" to a particular spot, it will be much simpler --- Additionally, if you do this, you can hardcode in the file path. – BobtimusPrime Aug 23 '17 at 21:01
0

I copied this from one of my projects that does something close. I'm capturing orders from a CSV file daily and keeping a list of those orders in the master spreadsheet until the processing is completed for those orders. This might be a little overkill, but it should do everything you need and help you make the process more robust. You can add a line into your command button click event:

Global Const AppName = "DailyMacro.xlsm"

Sub Command1_Click()
    call ImportOrders
End Sub

Public Sub ImportOrders()

    Dim iFile As String, WorkbookName As String, ValidFile As Boolean, Path As String
    Application.ScreenUpdating = False
    '--dialog box to select today's file
    iFile = ImportFilename()
    ValidFile = True
    If iFile <> "" Then
        WorkbookName = StripPath(iFile)
        If ConfirmExcelFile(WorkbookName) Then 
            Workbooks(WorkbookName).Activate
            With Worksheets(1)
                .Activate
                '--verify correct file type (depends on your needs)
                If Not (.Range("A1").Text = "H" And .Range("B1").Text = "PO") Then
                    ValidFile = False  'not a valid file
                Else
                    '--last row in column 'c'
                    LR = LastRow(Worksheets(1).Name, "C")
                    If LR < 2 Then ValidFile = False
                End If
                '--copy over today's data
                If ValidFile = True Then .Range("A2:AE" & LR - 1).Copy
            End With
            If ValidFile = True Then
                Workbooks(AppName).Activate
                With Worksheets(oFile)
                    .Activate
                    '--last row of existing data
                    LR = LastRow(oFile, "C")
                    '--append new rows to end 
                    .Range("A" & LR + 1).Select
                    ActiveSheet.Paste
                    Application.CutCopyMode = False
                End With
            Else
                MsgBox "Import file wrong format or empty. Please check and try again.", vbCritical, "ERROR"
            End If
        End If
        Workbooks(WorkbookName).Close
    End If
    Application.ScreenUpdating = True

End Sub

Private Function ImportFilename() As String

    Dim fName As String, fTitle As String, fFilter As String, LR As Long
    fTitle = "Please choose a file to open"
    fFilter = "Comma Separated Value *.csv* (*.csv*),"
    fName = Application.GetOpenFilename(Title:=fTitle, fileFilter:=fFilter)
    If fName = "False" Then
        MsgBox "No file selected.", vbExclamation, "Sorry!"
        Exit Function
    Else
        Workbooks.Open Filename:=fName
        ImportFilename = fName
    End If

End Function

Function StripPath(Filename) As String
    Dim X As Integer, NewName As String, saveName As String
    X = InStrRev(Filename, "\")
    If X <> 0 Then
        saveName = Mid(Filename, X + 1, Len(FileName))
    End If
    StripPath = saveName
End Function

Function ConfirmExcelFile(Filename As String) As Boolean
    On Error GoTo BadFile
    'confirm that we have valid excel file
    If Workbooks(Filename).Worksheets.Count > 0 Then
        'now check to see if there is any data contained
        With Workbooks(Filename).Worksheets(1)
            If LastRow(.Name, "C") > 2 Then
                ConfirmExcelFile = True
                Exit Function
            Else
                MsgBox "Selected file does not contain data.", vbExclamation, "Error!"
                Exit Function
            End If
        End With
    End If
BadFile:
    MsgBox "Selected file is not compatible.", vbExclamation, "Error!"
End Function

Function LastRow(Tabname As String, Col As String) As Long
   With Worksheets(Tabname)
       LastRow = .Cells(Rows.Count, Col).End(xlUp).Row
   End With
End Function
Dennis
  • 1
  • 2
  • Thank you Dennis, i will copy this and try to adjust it to my file, fingers crossed :D – Alexandra Aug 23 '17 at 20:53
  • Please note I made a change to the code. Check the StripPath() function and see if you need to copy that part again. – Dennis Aug 23 '17 at 21:18