I have a problem when I create macro in one workbook that use another workbook.
This is the code that I am using :
Private Sub CommandButton21_Click()
Set wb1 = Workbooks.Open("
http://europort/it_division/ITAC/Portal/Documentations/Proba 1.xlsx"
)
With wb1
FinalRow = .Worksheets("Sheet1")
.Cells(.Worksheets("Sheet1").Rows.Count, 1)
.End(xlUp).Row
For i = 1 To FinalRow
If TextBox21.Text = .Worksheets("Sheet1").Cells(i, 1).Value Then
MsgBox .Worksheets("Sheet1").Cells(i, 2).Text
Next i
End With
wb1.Close
End Sub
It's working fine but it opens another workbook and only when I click OK button it closes that workbook. I don't want to open this workbook, only to see result and not to see entire excel workbook. How can I do that? Please help.
This should do what you're after, based on your question:
Private Sub CommandButton21_Click()
Application.ScreenUpdating = False
msg = ""
Set wb1 = Workbooks.Open("http://europort/it_division/ITAC/Portal/Documentations/Proba 1.xlsx")
With wb1
FinalRow = .Worksheets("Sheet1").Cells(.Worksheets("Sheet1").Rows.Count, 1).End(xlUp).Row
For i = 1 To FinalRow
If TextBox21.Text = .Worksheets("Sheet1").Cells(i, 1).Value Then
msg = msg & .Worksheets("Sheet1").Cells(i, 2).Text & vbCr
Next i
End With
wb1.Close
Application.ScreenUpdating = True
If msg <> "" Then MsgBox msg
End Sub
The whole thing needs tidying up, you should declare etc. but as it stands now if your code works this should also work.
Related
I have this small piece of code:
NombreLibro = Application.GetOpenFilename()
Set Libro = Workbooks.Open(NombreLibro, , False)
If Val(Application.Version) > 15 Then 'I tried this but it doesn't solve the problem
Libro.AutoSaveOn = False
End If
With Libro
For i = 1 To .Worksheets.Count
If .Worksheets(i).CodeName = "Sheet1" Then 'HERE I HAVE THE PROBLEM
(doing something)
End If
Next i
End With
Sometimes the "if" is false even if the workbook actually has the "Sheet1".
But if I run this again, adding a stop in the code to check what is going on, then the piece of code works as expected.
I am downloading the workbooks from a company website and run the code right away.
I have OneDrive in my computer. So I am wondering if OneDrive is busy uploading the file and then Excel doesn't access it correctly?
What do you suggest I could try?
EDIT:
Following VBasic2008 suggestion (see his/her answer) I changed a little the code, but it kept failing. I then added a debug MsgBox:
For Each ws In Libro.Worksheets
MsgBox "CodeName: " & ws.CodeName & vbLf _
& "Name: " & ws.Name & vbLf & "Libro: " & Libro.Name 'I added this
If ws.CodeName = wsCodeName Then
wasFound = True
Exit For ' The worksheet is found, no need to loop anymore.
End If
Next ws
Result (shown in the MsgBox):
CodeName: 'blank!!!
Name: SheetName 'correct
Libro: LibroName 'correct
Is there a bug in Excel related to CodeNames?
EDIT2: (WORKAROUND)
I download the files from a company website, the data on the website is on a table and then a converter downloads it into Excel format.
I think the downloaded file is not quite Excel format and the CodeName is not filled. When Excel opens it and then the VBA editor is opened, Excel fills out the CodeName with a standard name.
In my case, as the fresh downloaded files have only one sheet, I can use this workaround:
For Each ws In Libro.Worksheets
If ws.CodeName = wsCodeName Or ws.CodeName = "" Then
wasFound = True
Exit For
End If
Next ws
This will work the first time the file is processed ws.CodeName = "" and the next times ws.CodeName = wsCodename
Using Worksheet CodeName
Option Explicit
Sub testCodeName()
Const wsCodeName As String = "Sheet1"
' Choose file (workbook, spreadsheet).
Dim NombreLibro As Variant
NombreLibro = Application.GetOpenFilename()
' Validate workbook.
If NombreLibro = False Then
MsgBox "You canceled.", vbExclamation, "Canceled"
Exit Sub
End If
' Open and create a reference to the workbook.
Dim Libro As Workbook: Set Libro = Workbooks.Open(NombreLibro, , False)
' Attempt to find the worksheet.
Dim ws As Worksheet
Dim wasFound As Boolean
For Each ws In Libro.Worksheets
If ws.CodeName = wsCodeName Then
wasFound = True
Exit For ' The worksheet is found, no need to loop anymore.
End If
Next ws
' Validate worksheet.
If Not wasFound Then
MsgBox "Worksheet not found.", vbExclamation, "Not Found"
Exit Sub
End With
' Continue with the code
With ws
' e.g. see if it's true.
MsgBox "Worksheet found:" & vbLf _
& "Name: " & .Name _
& vbLf & "CodeName: " & .CodeName, vbInformation, "Success"
End With
End Sub
I'm somewhat of a VBA noob but I wrote this simple code a while back to search for a worksheet and delete it:
Dim sht As Worksheet
For Each sht In ThisWorkbook.Worksheets
If Application.Proper(sht.Name) = Application.Proper("Company Data") Then
Sheets("Company Data").Select
Application.DisplayAlerts = False
ActiveWindow.SelectedSheets.Delete
Application.DisplayAlerts = True
End If
Next sht
Maybe this can help?
I have a really weird problem about VBA.
I tried to list circular references at activeworkbook and i have written below code for that. It only works if i press ALT+F11. So if VBA Editor window is open, code runs correctly but otherwise it is not working.
By the way, code is in a module at Addin and i call it from ribbon. You may see the code below.
Your help is highly appreciated. Bruteforce solution works. I hope someone can find decent solution than me.
Type SaveRangeCir
Val As Variant
Addr As String
Preaddress As String
Shtname As String
Workbname As String
End Type
Public OldCir() As SaveRangeCir
Sub DonguselBasvurulariBul(control As IRibbonControl)
Dim wba As Workbook
Dim ws As Worksheet
Dim wsa As Worksheet
Dim sht As Worksheet
Dim sht2 As Worksheet
Dim dummy As Worksheet
Dim Item As Range
Dim crcell As Range
Dim cll As Range
un = "Sayin " & Environ("UserName")
muyarcirc = MsgBox("Lutfen Oncelikle Dosyanizi Kaydedin" & vbNewLine & vbNewLine & _
"-->> Dosyanizi Kaydettiniz mi?", vbExclamation + vbYesNo, un)
If muyarcirc = vbno Then
muyar2 = MsgBox("Dongusel Basvuru Arama Islemi Iptal Edildi", vbInformation, un)
Exit Sub
End If
'BruteForce Solution
With Application
.DisplayAlerts = False
.ScreenUpdating = False
.EnableEvents = False
.VBE.MainWindow.Visible = True
.Wait Now + TimeValue("00:00:01")
.VBE.MainWindow.Visible = False
End With
On Error Resume Next
Set wba = ActiveWorkbook
Set wsa = wba.ActiveSheet
wba.Worksheets.Add
Set dummy = ActiveSheet
For Each sht2 In wba.Sheets
If sht2.Name = "Dongusel Basvurular" Then
sht2.Delete
End If
Next sht2
wba.Worksheets.Add
Set ws = wba.ActiveSheet
dummy.Delete
With ws
.Name = "Dongusel Basvurular"
.Range("A1") = "Dongusel Basvuru Hucresi"
.Range("B1") = "Dongusel Basvuru Hucresi Formul Degeri"
.Range("C1") = "Bagli Oldugu Alan"
.Range("D1") = "Bulundugu Sayfa"
.Range("E1") = "Bulundugu Dosya"
End With
With wba
For Each sht In .Worksheets
If sht.CodeName <> ws.CodeName Then
sht.Activate
crcell = Nothing
Do
Set crcell = sht.CircularReference
If Not crcell Is Nothing Then
ReDim Preserve OldCir(1 To crcell.Precedents.Cells.Count)
i = 0
For Each cll In crcell.Precedents
i = i + 1
OldCir(i).Addr = cll.Address
OldCir(i).Val = cll.Formula
OldCir(i).Preaddress = cll.Precedents.Address
OldCir(i).Shtname = cll.Parent.Name
OldCir(i).Workbname = cll.Parent.Parent.Name
cll.Value = cll.Value
Next cll
For j = LBound(OldCir) To UBound(OldCir)
lr = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ws.Cells(lr, 1) = OldCir(j).Addr
ws.Cells(lr, 2) = "'" & OldCir(j).Val
ws.Cells(lr, 3) = OldCir(j).Preaddress
ws.Cells(lr, 4) = OldCir(j).Shtname
ws.Cells(lr, 5) = OldCir(j).Workbname
ws.Hyperlinks.Add Anchor:=ws.Cells(lr, 1), Address:="", SubAddress:=ws.Cells(lr, 4) & "!" & ws.Cells(lr, 1), _
ScreenTip:="Dongusel Basvuru Hucresini Gormek icin Tiklayiniz"
Next j
Else
GoTo skipsheet
End If
Erase OldCir
Set crcell = sht.CircularReference
Loop While crcell.Cells.Count > 0
lr2 = ws.Cells(Rows.Count, 1).End(xlUp).Row
For m = 2 To lr2
If ActiveSheet.Name <> ws.Cells(lr2, "D") Then
wba.Sheets(ws.Cells(m, "D")).Activate
End If
Range(ws.Cells(m, 1)).Formula = "=" & Right(ws.Cells(m, 2), Len(ws.Cells(m, 2)) - 1)
Next m
End If
skipsheet:
Next sht
If ws.Range("A2") = "" Then
ws.Delete
wsa.Activate
m1 = MsgBox("Aktif Dosyada Dongusel Basvuru Bulunamadi", vbInformation, "Sayin " & Environ("UserName"))
Else
ws.Activate
ws.Range("A1:E1").EntireColumn.AutoFit
End If
End With
Erase OldCir
Set crcell = Nothing
With Application
.DisplayAlerts = True
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
I ran into a similar problem using VBA in MS Access. I understand you are using VBA Excel but I thought I'd post my personal experience in case it helps.
I have an Access form with a button that opens another form. The button is coded with VBA. If the VBA Editor was not open when I clicked the button then the new form would open but Form_Load() wouldn't trigger. If the VBA editor was open when I clicked the button then Form_Load() triggered as intended.
I did not have On Error Resume Next hiding any errors and all my variables were set with Option Explicit.
To troubleshoot the issue, I added a number of msgboxes throughout the code to narrow down where the problem was occurring. After adding a msgbox to the Click() event of the button I realized that the connection was somehow re-established and the code no longer needed the VBA editor open. After realizing this, I deleted the msgbox from the code, closed the application, re-opened the application without the VBA editor and from then on the VBA executed as intended.
Unfortunately, I came upon a solution while troubleshooting so I cannot provide an explanation as to why this worked but sometimes an explanation is not needed as long as you get it working again!
Hope this helps.
I had the same problem
However, it appeared have been caused by first using a message box with no return variable, then extending it to include a return, ie ret = msgbox(
Deleted the message box, code worked, closed and saved the project, reopened and message box with return variable added and now it run even without the editor open.
I'm using the following code to copy from an excel file starting with "Backorder Details":
Sub INSERT()
Dim Wb1 As Workbook, wb2 As Workbook, wB As Workbook
Dim rngToCopy As Range
Dim countEND As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Sheets("RAW_DATA").Select
Worksheets("RAW_DATA").Range("A3:CA45000").ClearContents
If ActiveSheet.AutoFilterMode Then ActiveSheet.AutoFilter.ShowAllData
For Each wB In Application.Workbooks
If Left(wB.Name, 17) = "Backorders Detail" Then
Set Wb1 = wB
Exit For
End If
Next
If Not Wb1 Is Nothing Then
Set wb2 = ThisWorkbook
With Wb1.Sheets(2)
Set rngToCopy = .Range("A3:BX3", .Cells(.Rows.Count, "A").End(xlUp))
End With
wb2.Sheets("RAW_DATA").Range("A3:BX3").Resize(rngToCopy.Rows.Count).Value = rngToCopy.Value
End If
With wb2.Sheets("RAW_DATA")
countEND = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("BY3:BY" & countEND).Formula = "=IFERROR(IF(AND(VLOOKUP(VALUE(AS3);BG_DATA!A:A;1;FALSE)=(VLOOKUP(VALUE(AS3);BG_DATA!A:A;1;FALSE));(AF3>0));"""";""x"");""x"")" 'Check
.Range("BZ3:BZ" & countEND).Formula = "=VLOOKUP(VALUE(AS3);BG_DATA!A:I;9;FALSE)" 'Vendor'
.Range("CA3:CA" & countEND).Formula = "=VLOOKUP(VALUE(AS3);BG_DATA!A:J;10;FALSE)" 'Planner
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "DONE!"
End Sub
I copied this function from another excel file I've made. It worked pretty good. But for some reason the following part is giving me an error now:
With wb2.Sheets("RAW_DATA")
countEND = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("BY3:BY" & countEND).Formula = "=IFERROR(IF(AND(VLOOKUP(VALUE(AS3);BG_DATA!A:A;1;FALSE)=(VLOOKUP(VALUE(AS3);BG_DATA!A:A;1;FALSE));(AF3>0));"""";""x"");""x"")" 'Check
.Range("BZ3:BZ" & countEND).Formula = "=VLOOKUP(VALUE(AS3);BG_DATA!A:I;9;FALSE)" 'Vendor'
.Range("CA3:CA" & countEND).Formula = "=VLOOKUP(VALUE(AS3);BG_DATA!A:J;10;FALSE)" 'Planner
End With
Run-time error 1004 - Application-defined or object defined error.
I googled this but didn't find a solution. Excel file was an XLSX and is an XLSM now. Can someone please tell what the problem is?
You are using semicolon ; as a delimiter in your formula, but the delimiter depends on the localization of your workbook. Use comma , instead:
With wb2.Sheets("RAW_DATA")
countEND = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("BY3:BY" & countEND).Formula = "=IFERROR(IF(AND(VLOOKUP(VALUE(AS3),BG_DATA!A:A,1,FALSE)=(VLOOKUP(VALUE(AS3),BG_DATA!A:A,1,FALSE)),(AF3>0)),"""",""x""),""x"")" 'Check
.Range("BZ3:BZ" & countEND).Formula = "=VLOOKUP(VALUE(AS3),BG_DATA!A:I,9,FALSE)" 'Vendor'
.Range("CA3:CA" & countEND).Formula = "=VLOOKUP(VALUE(AS3),BG_DATA!A:J,10,FALSE)" 'Planner
End With
Alternatively you could use .FormulaLocal instead of .Formula, but it will work only in the workbooks where localization defines semicolon as the delimiter.
I am creating a few macros to do the following in Excel 2010:
1. Upon creating a new worksheet ask for what the user wants to name his/her worksheet and sets the new worksheet to the name provided; calls Sort_Active_Book and Rebuild_TOC in order
2. Sort_Active_Book: Asks the user if he/she wants to sort the workbook's worksheets in ascending/descending order and proceeds to do so.
3. Rebuild_TOC: Deletes the Table of Contents page and rebuilds it based on all the worksheets in the workbook minus the TOC itself.
My problem is Excel keeps asking me to input the name of the new worksheet to be created and does not progress any further in the code. I notice it manages to create the named worksheet and asks me if I would like to sort ascending or descending but then proceeds to ask me again the name of the new worksheet. Could anyone please point out how to fix this and provide a code fix (if possible) please?
What I have already
This code portion is from ThisWorkbook, this is what prompts the user for the name of the worksheet upon creation.
Private Sub Workbook_NewSheet(ByVal Sh As Object)
Dim sName As String
Dim bValidName As Boolean
Dim i As Long
bValidName = False
Do While bValidName = False
sName = InputBox("Please name this new worksheet:", "New Sheet Name", Sh.Name)
If Len(sName) > 0 Then
For i = 1 To 7
sName = Replace(sName, Mid(":\/?*[]", i, 1), " ")
Next i
sName = Trim(Left(WorksheetFunction.Trim(sName), 31))
If Not Evaluate("ISREF('" & sName & "'!A1)") Then bValidName = True
End If
Loop
Sh.Name = sName
Call Sort_Active_Book
Call Rebuild_TOC
End Sub
These two macros are in "Module 1":
Sub Sort_Active_Book()
Dim TotalSheets As Integer
Dim p As Integer
Dim iAnswer As VbMsgBoxResult
' Move the TOC to the begining of the document.
Sheets("TOC").Move Before:=Sheets(1)
' Prompt the user as to which direction they wish to
' sort the worksheets.
iAnswer = MsgBox("Sort Sheets in Ascending Order?" & Chr(10) & "Clicking No will sort in Descending Order", vbYesNoCancel + vbQuestion + vbDefaultButton1, "Sort Worksheets")
For TotalSheets = 1 To Sheets.Count
For p = 2 To Sheets.Count - 1
' If the answer is Yes, then sort in ascending order.
If iAnswer = vbYes Then
If UCase$(Sheets(p).Name) = "TOC" Then
Sheets(p).Move Before:=Sheets(1)
ElseIf UCase$(Sheets(p).Name) > UCase$(Sheets(p + 1).Name) Then
Sheets(p).Move After:=Sheets(p + 1)
End If
' If the answer is No, then sort in descending order.
ElseIf iAnswer = vbNo Then
If UCase$(Sheets(p).Name) = "TOC" Then
Sheets(p).Move Before:=Sheets(1)
ElseIf UCase$(Sheets(p).Name) < UCase$(Sheets(p + 1).Name) Then
Sheets(p).Move After:=Sheets(p + 1)
End If
End If
Next p
Next TotalSheets
End Sub
and
Sub Rebuild_TOC()
Dim wbBook As Workbook
Dim wsActive As Worksheet
Dim wsSheet As Worksheet
Dim lnRow As Long
Dim lnPages As Long
Dim lnCount As Long
Set wbBook = ActiveWorkbook
With Application
.DisplayAlerts = False
.ScreenUpdating = False
End With
' If the TOC sheet already exist delete it and add a new worksheet.
On Error Resume Next
With wbBook
.Worksheets(“TOC”).Delete
.Worksheets.Add Before:=.Worksheets(1)
End With
On Error GoTo 0
Set wsActive = wbBook.ActiveSheet
With wsActive
.Name = “TOC”
With .Range(“A1:B1”)
.Value = VBA.Array(“Table of Contents”, “Sheet # – # of Pages”)
.Font.Bold = True
End With
End With
lnRow = 2
lnCount = 1
' Iterate through the worksheets in the workbook and create sheetnames, add hyperlink
' and count & write the running number of pages to be printed for each sheet on the TOC.
For Each wsSheet In wbBook.Worksheets
If wsSheet.Name <> wsActive.Name Then
wsSheet.Activate
With wsActive
.Hyperlinks.Add .Cells(lnRow, 1), “”, _
SubAddress:=”‘” & wsSheet.Name & “‘!A1”, _
TextToDisplay:=wsSheet.Name
lnPages = wsSheet.PageSetup.Pages().Count
.Cells(lnRow, 2).Value = “‘” & lnCount & “-” & lnPages
End With
lnRow = lnRow + 1
lnCount = lnCount + 1
End If
Next wsSheet
wsActive.Activate
wsActive.Columns(“A:B”).EntireColumn.AutoFit
With Application
.DisplayAlerts = True
.ScreenUpdating = True
End With
End Sub
You are creating a new sheet with sub Rebuild_TOC. Causing the newsheet macro to run again.
You will need to avoid running the newsheet macro by adding a enableevents = false and true surrounding your code when creating a new sheet for your TOC. The rest of your code appears to be working as you want it to.
Application.EnableEvents = False
With wbBook
.Worksheets("TOC").Delete
.Worksheets.Add Before:=.Worksheets(1)
End With
Application.EnableEvents = True
Why would you want to delete the TOC worksheet, why not just update it?
The following macro works fine without the 1st and 3rd lines emphasised (i.e. password protection). When I add the code the macro works the first time but if I open the file again, it returns a run time error 'pastespecial method of range class failed' at the line second line emphasised. The purpose of the macro is to open a purchase order template, increment the purchase order number by one, complete a second log file with date, purchase order number and user name and re-save the purchase order template under a different file name:
Private Sub Workbook_Open()
If ThisWorkbook.ReadOnly Then
MsgBox "Please use dropdown arrow next to filename within SharePoint and select 'Edit in Microsoft Office Excel' instead."
ThisWorkbook.Close
End If
Range("L14") = Range("L14") + 1
ActiveWorkbook.Save
Range("L14").Copy
Workbooks.Open Filename:="\\ehfnp01\users\gminter\My Documents\PO Log Elite\PO Log Elite.xls"
Workbooks("PO Log Elite.xls").Activate
Dim lst As Long
With ActiveWorkbook.Sheets("Sheet1")
*.Unprotect Password:="2"*
lst = .Range("B" & Rows.Count).End(xlUp).Row + 1
**.Range("B" & lst).PasteSpecial xlPasteValuesAndNumberFormats**
End With
With ActiveWorkbook.Sheets("Sheet1")
lst = .Range("A" & Rows.Count).End(xlUp).Row + 1
.Range("A" & lst) = Now
End With
With ActiveWorkbook.Sheets("Sheet1")
lst = .Range("C" & Rows.Count).End(xlUp).Row + 1
.Range("C" & lst).Value = Environ("Username")
*.Protect Password:="2"*
End With
ActiveWorkbook.Save
ActiveWorkbook.Close
ThisFile = Application.DefaultFilePath & "\" & Range("G14").Value & Range("L14").Text
ActiveWorkbook.SaveAs Filename:=ThisFile
Range("L15") = Now
Range("E20").Value = Environ("Username")
ScreenUpdating = False
Set Rng = Intersect(ActiveSheet.UsedRange, Range("e20"))
For Each C In Rng
C.Value = StrConv(C.Value, vbUpperCase)
Next
ScreenUpdating = True
Cells.Locked = False
Range("G14:N15,E20:N20").Locked = True
ActiveSheet.Protect Password:="1"
Dim x As Integer
On Error Resume Next
With ActiveWorkbook.VBProject
For x = .VBComponents.Count To 1 Step -1
.VBComponents.Remove .VBComponents(x)
Next x
For x = .VBComponents.Count To 1 Step -1
.VBComponents(x).CodeModule.DeleteLines _
1, .VBComponents(x).CodeModule.CountOfLines
Next x
End With
On Error GoTo 0
End Sub
Any help would be greatly appreciated as I can't find any similar examples of this.
What happens when you explicitly declare your Objects/Variables and then work with them? That ways you do the copy just before you paste. This will ensure that the clipboard doesn't get cleared for any reason which Excel is unfortunately famous for...
Private Sub Workbook_Open()
Dim rng As Range
Dim newWb As Workbook, wb As Workbook
Dim lst As Long
If ThisWorkbook.ReadOnly Then
MsgBox "Please use dropdown arrow next to filename within SharePoint and select 'Edit in Microsoft Office Excel' instead."
ThisWorkbook.Close
Exit Sub '<~~ ?
End If
Set rng = ThisWorkbook.Sheets("Sheet1").Range("L14")
rng.Value = rng.Value + 1
ThisWorkbook.Save
Set newWb = Workbooks.Open(Filename:="\\ehfnp01\users\gminter\My Documents\PO Log Elite\PO Log Elite.xls")
Set wb = Workbooks("PO Log Elite.xls")
With wb.Sheets("Sheet1")
.Unprotect Password:="2"
lst = .Range("B" & .Rows.Count).End(xlUp).Row + 1
rng.Copy '<~~ Do the copy here
.Range("B" & lst).PasteSpecial xlPasteValuesAndNumberFormats
End With
'
'~~> Rest of the code
'
End Sub