Excel VBA .Select only works on Sheets(1) - excel

I am currently setting new designs Excel files to fit better on mobile devices. But the old designs files are also needed to some clients and I need to export the data to old design files from new design files.
Old design file contains 4 Sheets. After exporting the data I want to select Cell A1 on all sheets. But I was only able to Range("A1").Select or Cells(1,1).Select on Sheets(1) only. If I set on other sheets I got "Run Time Error '1004': Select method of Range Class failed". Below are the VBA Codes along with some comments. Please help.
Set Old_CV = Application.Workbooks.Open(Old_File_Path)
ThisWorkbook.Worksheets("Data_Import").ListObjects("tbl_part2").DataBodyRange.Copy
wsTarget = ThisWorkbook.Worksheets("Data_Import").Range("rng_CV_Part2_Old")
Old_CV.Worksheets(wsTarget).Range(wsSource.Range("rng_P2_A1_Start_Old").Value).PasteSpecial xlPasteValuesAndNumberFormats
Old_CV.Activate
Old_CV.Sheets(1).Cells(1, 1).Select 'This line works even without Old_CV.Active
Old_CV.Sheets(2).Cells(1, 1).Select 'This and below lines don't work even with Old_CV.Active and showing Runtime Error
Old_CV.Sheets(3).Cells(1, 1).Select
Old_CV.Sheets(4).Cells(1, 1).Select
Please Help.

Activate & Select
Select and Activate are usually to be avoided, but this task you cannot do without them.
A good idea is to do this from the last to the first worksheet, so the first stays selected (activated).
In the first two examples you are activating each worksheet before selecting the cell, so you need not activate the workbook.
In the third example you have to activate the workbook first and at the end you have to select the first worksheet 'to get rid of the group'.
The out-commented lines where used to create critical working examples in which first another workbook is active.
The Code
Option Explicit
Sub test1()
' Dim Old_CV As Workbook
' Set Old_CV = ThisWorkbook
' Workbooks("Book2").Activate
' ActiveSheet.Cells(1, 1).Value = 1
Old_CV.Worksheets(4).Activate
Old_CV.Worksheets(4).Cells(1, 1).Select
Old_CV.Worksheets(3).Activate
Old_CV.Worksheets(3).Cells(1, 1).Select
Old_CV.Worksheets(2).Activate
Old_CV.Worksheets(2).Cells(1, 1).Select
Old_CV.Worksheets(1).Activate
Old_CV.Worksheets(1).Cells(1, 1).Select
End Sub
Sub test2()
' Dim Old_CV As Workbook
' Set Old_CV = ThisWorkbook
' Workbooks("Book2").Activate
' ActiveSheet.Cells(1, 1).Value = 2
Dim n As Long
For n = 4 To 1 Step -1
Old_CV.Worksheets(n).Activate
Old_CV.Worksheets(n).Cells(1, 2).Select
Next n
End Sub
Sub test3()
' Dim Old_CV As Workbook
' Set Old_CV = ThisWorkbook
' Workbooks("Book2").Activate
' ActiveSheet.Cells(1, 1).Value = 3
Old_CV.Activate
Old_CV.Worksheets(Array(1, 2, 3, 4)).Select
ActiveSheet.Cells(1, 3).Select
Old_CV.Worksheets(1).Select
End Sub

Related

How do I Copy spreadsheet formats while updating a given cell with a counter in vba?

The project I am working on is the creation of a macro in Excel that copies the format from a given tab and duplicates it into subsequent tabs.
Just as a heads up, this is my first exposure to VBA but I do have some experience with C++
I have already found a good template to work with for the above that does the task well enough and is as follows:
Public Sub CopySheetAndRenameByCell()
Dim wks As Worksheet
Set wks = ActiveSheet
ActiveSheet.Copy After:=Worksheets(Sheets.Count)
If wks.Range("H9").Value <> "" Then
On Error Resume Next
ActiveSheet.Name = wks.Range("H9").Value
End If
wks.Active
End Sub
The problem I am trying to solve at this point is integrating a line of code that acts as a counter which updates the value of the given cell by +1 with every new sheet and references the updated cell for the sheet label.
Any insights would be appreciated.
Public Sub AddNewPage()
Sheets(Sheets.Count).Select 'references last sheet in workbook
Dim wks As Worksheet 'establish static variable wks to reference worksheets
Set wks = ActiveSheet 'set wks to be the defined active sheet
ActiveSheet.Copy After:=Worksheets(Sheets.Count)
Range("H9").Value = Range("H9").Value + 1 'sets value of cell H9 in new worksheets to sequentially increase by 1
If wks.Range("H9").Value <> "" Then
On Error Resume Next
wks = Sheets(Sheets.Count).Select 'references last sheet in workbook
ActiveSheet.Name = wks.Range("H9").Value + 1 'sets page title to sequentially increase by 1 with each iteration
End If
wks.Activate
End Sub
This is the solution I came up with with a little help from the internet. Thank you for the responses.

How to Copy data from Source to multiple Destination File if Macros code is in Source file?

Suppose I have Source.xlsm( it has only one sheet file) ,it has data in that sheet. and I have 10 different destination.xlsx file in that we have multiple sheets suppose abc, efg, ijk. I have to copy whole data present in Source.xlsx file to 10 different destination excel (under sheet_name ijk).
I want to have macro code in source.xlsm when i click on the button it should copy whole data to 10 different destination files(under sheet_name ijk).
stuck for days please help me
Private Sub CommandButton1_click()
Dim wb As Workbook
Dim lRow As Long
Dim lcol As Long
Dim total As String
ThisWorkbook.Worksheets("ViewList").Select
lRow = Cells(Rows.Count, 1).End(xlUp).Row
lcol = Cells(1, Columns.Count).End(xlToLeft).Column
Range(Cells(1, 1), Cells(lRow, lcol)).Copy
Set wb = Workbooks.Open("C:\Users\Desktop\Destination.xlsx")
wb.Worksheets("abc").Activate
ActiveSheet.Paste
ActiveWorkbook.Save
ActiveWorkbook.Close savechanges = True
ThisWorkbook.Worksheets("ViewList").Activate
ThisWorkbook.Worksheets("ViewList").Cells(1, 1).Select
Application.CutCopyMode = False
End Sub
This code is pasting data in the middle of destination file i want to paste it in from cell (1,1)
I recommend the following
Private Sub CommandButton1_click()
Dim wsViewList As Worksheet
Set wsViewList = ThisWorkbook.Worksheets("ViewList")
Dim lRow As Long
lRow = wsViewList.Cells(wsViewList.Rows.Count, 1).End(xlUp).Row
Dim lcol As Long
lcol = wsViewList.Cells(1, wsViewList.Columns.Count).End(xlToLeft).Column
Dim wb As Workbook
Set wb = Workbooks.Open("C:\Users\Desktop\Destination.xlsx")
wsViewList.Range("A1", wsViewList.Cells(lRow, lcol)).Copy Destination:=wb.Worksheets("abc").Range("A1").Paste
'wb.Save 'this statement is not needed because you save on closing the workbook. Otherwise you would save twice which takes twice the time.
wb.Close SaveChanges:=True
wsViewList.Cells(1, 1).Select 'this is actually not needed unless you want to move the users view to that cell. If that is not what you need remove that line.
Application.CutCopyMode = False
End Sub
Your code would work without any .Select or .Activate statements. Also your code needs to know where exactly you want to paste so you should specify the destination cell not only the worksheet. Also it is a good practice do do the copy and past in one statemant or at least don't do any further steps between copy and paste because that can interfere with the copyied range.
Finally named parameters need to be submitted with := not with = sign. I highly recommend you to activate Option Explicit because the line
ActiveWorkbook.Close savechanges = True
does actually do the oposite of what you think:
savechanges = True because of the missing := sees savechanges as an undeclared variable of type Variant and compares if this is True. Since it is not declared and not initialized with any value the result of this statement is False.
Finally you submit that result False as first parameter to ActiveWorkbook.Close so it is the same as writing ActiveWorkbook.Close False. So what your code actually does is it closes the workbook without saving changes.
If you used Option Explicit it would have notified you that savechanges is an undeclared variable. This way this fault would have been prevented. Without that notification it is much harder to see and find that issue.
Therefore I recommend always to activate Option Explicit: In the VBA editor go to Tools › Options › Require Variable Declaration.

Programmatically detect the existence and size of tables then add them to another workbook

I have a workbook that crashes often. I suspect it's corrupted. So, I wrote the following code to copy it sheet by sheet to a new workbook. The size of the new workbook is now 40% less. Everything seems to work fine except the code doesn't copy tables. ListObjects doesn't seem to have a count property. So, it's not straight forward to detect the number of tables in a sheet.
How do I detect the existence, size, and location of tables? Once that info is known, I think it'd be quite easy to go to the target sheet and add tables. Thanks in advance for any help.
Sub copy_all()
'copy sheet by sheet from myworkbook.xlsb to the calling workbook
Dim rng As Range
Dim i As Integer
With Workbooks("myworkbook.xlsb")
For i = 1 To .Sheets.Count
Set rng = .Sheets(i).UsedRange
ThisWorkbook.Sheets(i).Range("A1").Resize(rng.Rows.Count, rng.Columns.Count).Cells.Value = rng.Cells.Value
ThisWorkbook.Sheets(i).Range("A1").Resize(rng.Rows.Count, rng.Columns.Count).Cells.Formula = rng.Cells.Formula
ThisWorkbook.Sheets(i).Range("A1").Resize(rng.Rows.Count, rng.Columns.Count).Cells.ColumnWidth = rng.Cells.ColumnWidth
rng.Copy
ThisWorkbook.Sheets(i).Range("A1").PasteSpecial Paste:=xlPasteFormats
ThisWorkbook.Sheets(i).Name = .Sheets(i).Name
ThisWorkbook.Sheets(i).Tab.ColorIndex = .Sheets(i).Tab.ColorIndex
Next i
End With
End Sub
Try the next code, to find the ListObjects and their range address, please:
Sub testAllListObjects()
Dim T As ListObject, sh As Worksheet
For Each sh In ActiveWorkbook.Worksheets
If sh.ListObjects.Count > 0 Then
For Each T In sh.ListObjects
Debug.Print sh.Name, T.Name, T.Range.address
Next
End If
Next
End Sub

Pasting into Excel ActiveX ComboBox

I'm trying to copy data from one workbook into another workbook that is build as a survey.
In the survey form, we are using ActiveX controls for combo boxes and check boxes. I left two samples of ways I have tried (and failed).
Sub TransferData()
Set Source = Workbooks.Open("FromHere.xlsm")
Set qstnr = Workbooks.Open("ToHere.xlsx")
' Banner Form Classification
Source.Activate
Cells(8, 2).Copy
qstnr.Activate
Set Cbo_Classification = qstnr.OLEObjects("Cbo_Classification")
With Cbo_Classification.Object
.Text = "Not sure what to do here"
End With
' Reporting Organization
Source.Activate
Cells(9, 2).Copy
qstnr.Activate
'ActiveSheet.OLEObjects("Cbo_RptOrg").PasteSpecial Paste:=xlPasteValues
End Sub
EDIT: I have been able to get the object to be pasted into when working in the same workbook with the copy below. I don't understand why it's not successful when working outside the document.
Sub TransferObjects()
Dim wbk As Workbook: Set wbk = Workbooks.Open("CopyFrom.xlsm")
Dim tmplt As Workbook: Set tmplt = Workbooks.Open("CopyTo.xlsx")
Dim qstnr As Worksheet
Set qstnr = tmplt.Sheets("Sheet1")
qstnr.OLEObjects("Cbo_RptOrg").Object.Value = Range("K12").Value
End Sub
' Reporting Organization
Source.Activate
Dim Cbo_RptOrg As Variant
Cbo_RptOrg = Cells(2, 9).Value
qstnr.OLEObjects("Cbo_RptOrg").Object.Value = Cbo_RptOrg
This ended up working. Using a variable as suggested.

Dynamically Copy Range of Cells from Closed Workbook?

I would like to copy a range of cells in a closed notebook that does not have a static set of rows. I would like to copy it into an active workbook.
I am trying to dynamically copy all entries under the column of F from file 'test.xlsx' from the 'exception' worksheet. The macro runs without issue if there I use static referencing instead. Here is the code that I am running, it gives me a runtime error for the line that copies the data.
Sub GetClassID()
Dim App As New Excel.Application
Dim wsActive As Worksheet
Set wsActive = ThisWorkbook.ActiveSheet
Dim wbImport As Workbook
Set wbImport = App.Workbooks.Open(Filename:="C:\Test.xlsx",
UpdateLinks:=True, ReadOnly:=True)
wbImport.Worksheets("Exception").Range("F2",Range("F2").end(xldown)).Copy
wsActive.Range("A2").PasteSpecial Paste:=xlPasteFormats
wsActive.Range("A2").PasteSpecial Paste:=xlPasteValues
App.CutCopyMode = False
wbImport.Close SaveChanges:=False
App.Quit
End Sub
Error I get is runtime erorr '1004': Interface not registered
Assuming you run this in an Excel VBA? You don't need to open the other workbook as an Excel.Application, just remove the app out of it and open the workbook normally:
Sub GetClassID()
Dim wsActive As Worksheet
Set wsActive = ThisWorkbook.Sheets("Another Sheet Name")
Dim wbImport As Workbook
Set wbImport = Workbooks.Open(Filename:="C:\Test.xlsx", UpdateLinks:=True, ReadOnly:=True)
With wbImport.Worksheets("Exception")
.Range("F2", .Range("F2").End(xlDown)).Copy
End With
wsActive.Range("A2").PasteSpecial Paste:=xlPasteFormats
wsActive.Range("A2").PasteSpecial Paste:=xlPasteValues
App.CutCopyMode = False
wbImport.Close SaveChanges:=False
App.Quit
End Sub
In my experience, the most effective way to copy a dynamic range is to create a variable as an integer and assign the row of the last cell to be copied (or column if needing to select a row of data across to a certain point. I usually accomplish it with something like this:
Dim R as Integer
With ThisWorkbook.Worksheets
R = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
Then you can plug in 'R' for the row number in a range to make it dynamic each time the macro is ran. For instance: .Range("A1:A" & R).Copy would copy the used range in Column A. It also makes it really easy to reference the last row for loops and such continuously throughout your code. Hope this helps!

Resources