The code below is used to update several worksheets in different locations. It will update a particular module that I will specify. This code was working good as of last week. But starting this week it is not working anymore. Everytime, I run this code, it will throw an error during saving of the workbook. The error is "run-time error '1004' Document not saved". I did not change the source code, it was puzzling for me because it used to work but now it is not working. Anybody can suggest anything for me to solve this problem? I am guessing maybe because Excel updates itself and there were some changes in the new updates. The microsoft excel that I am using is Microsoft 365 MSO (Version 2209 Build 16.0.15629.20200) 64-bit. Can you guys suggest other code that works that could replace a module in an excel file given the source is in a text file as .bas extension.
Thanks.
Sub Update_VBA_Module_Pricing_Tool()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim wbUpdate As Workbook
Dim ModuleFile As String
Set wsActive = ThisWorkbook.Sheets("Pricing")
'Loop Thru Files Listed in Col A
i = 2
While wsActive.Range("A" & i).Value <> ""
If wsActive.Range("C" & i).Value = "Y" Then
Application.StatusBar = "Updating " & wsActive.Range("B" & i).Value & " ..."
'DirFile = Workbooks.Open(wsActive.Range("A" & i).Value)
If IsFile(wsActive.Range("A" & i).Value) = False Then
MsgBox wsActive.Range("B" & i).Value & " does not exist..."
GoTo proceed_to_next:
End If
'Dim wbTemp As Workbook
'Set wbTemp = Workbooks.Open("D:\Spark RE Analytics, LLC\Spark Vault - General\02-Pricing Properties\Tuesday-pm-G-BLD\1. Pricing Tool\Week 111 22-10-23\1_BLD Portfolio Pricing Tool Week 111.xlsm")
Set wbUpdate = Workbooks.Open(wsActive.Range("A" & i).Value)
Set vbp = Workbooks(wbUpdate.Name).VBProject
'Loop Thru VBA Modules in Col D
j = 2
While wsActive.Range("H" & j).Value <> ""
If wsActive.Range("J" & j).Value = "Y" Then
'Set module to Process
ModuleFile = wsActive.Range("H" & j).Value
modulename = wsActive.Range("I" & j).Value
'Replace Module in Workbook
Set vbp = Workbooks(wbUpdate.Name).VBProject
With vbp.VBComponents
.Remove vbp.VBComponents(modulename)
'.Import ModuleFile
Set temp = .Import(ModuleFile)
temp.Name = modulename
End With
' end of insert other things to file
End If
j = j + 1
Wend
'Save File
wbUpdate.Save
wbUpdate.Close False
Application.StatusBar = "Finished Updating " & wsActive.Range("B" & i).Value & " ..."
End If
proceed_to_next:
i = i + 1
Wend
apps_exit:
MsgBox "Done!"
End Sub
Related
I am making a tool in excel VBA to bulk create some kind of invoices to each customer. We are making LIVE streams and selling kids clothing, then we write all our orders to excel sheet. Example:
orders list
Then we have to sort all those orders by customer (there are many of them) and create some kind of invoice for each customer. Example: "invoice template"
I use this code to bulk create those and download as pdfs.
Sub Create_PDF_Files()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim dsh As Worksheet
Dim tsh As Worksheet
Dim setting_Sh As Worksheet
Set dsh = ThisWorkbook.Sheets("uzsakymai")
Set tsh = ThisWorkbook.Sheets("lapukas")
Set setting_Sh = ThisWorkbook.Sheets("Settings")
Application.DisplayStatusBar = True
Application.StatusBar = ""
Dim i As Integer
Dim File_Name As String
For i = 2 To dsh.Range("A" & Application.Rows.Count).End(xlUp).Row
Application.StatusBar = i - 1 & "/" & dsh.Range("A" & Application.Rows.Count).End(xlUp).Row - 1
tsh.Range("D1").Value = dsh.Range("C" & i).Value
tsh.Range("A4").Value = dsh.Range("B" & i).Value
tsh.Range("B4").Value = dsh.Range("A" & i).Value & " - " & dsh.Range("E" & i).Value
tsh.Range("P4").Value = dsh.Range("D" & i).Value
File_Name = dsh.Range("A" & i).Value & "(" & dsh.Range("C" & i).Value & "-" & dsh.Range("D" & i).Value & ").pdf"
tsh.ExportAsFixedFormat xlTypePDF, setting_Sh.Range("F4").Value & "\" & File_Name
Next i
Application.StatusBar = ""
MsgBox "Done"
End Sub
But what it does is creating invoice for each item.
EXAMPLE
Any ideas how could I make it work for me as I want it to work?
---EDIT---
After ALeXceL answer, it seems to have some bugs. I changed my code to his code, and I see some progress in creating this program, but what it does, is it shows first item correctly, but all the other items are appearing starting on A24 cell. EXAMPLE
---EDIT---
IT WORKS!!!
Assuming that "uzsakymai" is "orders", the 'data sheet' (dsh) and "lapukas" is the 'template' sheet (tsh), I did these changes, added some counters, in order to the logic flows the right way:
Important: before put this code to run you MUST classify the 'orders' table (dsh, or "uzsakymai") first by Name, then, by Size (as you wish, according to the images posted)
Option Explicit
Sub Create_PDF_Files()
Dim Orders_sh As Worksheet
Dim Template_sh As Worksheet
Dim setting_Sh As Worksheet
Dim oCell As Excel.Range
Dim strKey_TheName As String
Dim lngTemplate_A As Long
Dim lngSumOfItems As Long
Dim dblSumOfValues As Double
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Set Orders_sh = ThisWorkbook.Sheets("uzsakymai")
Set Template_sh = ThisWorkbook.Sheets("lapukas")
Set setting_Sh = ThisWorkbook.Sheets("Settings")
Application.DisplayStatusBar = True
Application.StatusBar = ""
Dim lngI As Long
Dim File_Name As String
'At this point, the Orders_sh worksheet should already have its fields properly sorted/ordered. (Name, then Size)
lngI = 2
Application.StatusBar = lngI - 1 & "/" & Orders_sh.Range("A11").End(xlUp).Row - 1 'a maximum of 10 items can be written here!
Set oCell = Orders_sh.Range("A" & lngI) ' the initial cell
Do
strKey_TheName = UCase(Orders_sh.Range("C" & lngI).Value)
lngSumOfItems = 0
dblSumOfValues = 0
Do
Template_sh.Range("D1").Value = Orders_sh.Range("C" & lngI).Value
lngTemplate_A = IIf(lngSumOfItems = 0, 4, Template_sh.Range("A10").End(xlUp).Offset(1, 0).Row)
Template_sh.Range("A" & lngTemplate_A).Value = Orders_sh.Range("B" & lngI).Value
Template_sh.Range("B" & lngTemplate_A).Value = Orders_sh.Range("A" & lngI).Value & " - " & Orders_sh.Range("E" & lngI).Value
Template_sh.Range("P" & lngTemplate_A).Value = Orders_sh.Range("D" & lngI).Value
lngSumOfItems = lngSumOfItems + 1
dblSumOfValues = dblSumOfValues + Orders_sh.Range("D" & lngI).Value
File_Name = lngSumOfItems & "(" & Orders_sh.Range("C" & lngI).Value & "-" & VBA.Round(dblSumOfValues, 0) & ").pdf"
lngI = lngI + 1
Set oCell = oCell.Offset(1, 0)
Loop Until strKey_TheName <> UCase(oCell.Offset(0, 2).Value)
Template_sh.ExportAsFixedFormat xlTypePDF, setting_Sh.Range("F4").Value & "\" & File_Name
Template_sh.Range("D1").Value = ""
Template_sh.Range("A4:P10").ClearContents
Loop Until Len(oCell.Value) = 0
Application.StatusBar = ""
MsgBox "Done"
End Sub
I created a VBA macro that formats and creates charts out of raw data. I have added functionality to track usage of the macro and record usage (username, timestamp, client name) to a .txt file on our database.
The problem I am running into is that I want the usage tracker to be blind to the end user. However, I am getting windows popping up showing a save bar to the directory path. I've tried searching around for a solution to keep this hidden but I am unable to find any code that I'm able to implement to solve.
I expected the following inputs to hide all windows. I am not quite sure if I need more elaborate code to hide the save window.
Application.DisplayAlerts = False
Application.DisplayStatusBar = False
Application.ScreenUpdating = False
Application.EnableEvents = False�
Here is the code Im using to save usage:
'Usage Tracker'
On Error Resume Next
Dim wb As Workbook: Set wb = ActiveWorkbook
''''tracking file location
Dim strFilename As String: strFilename = "\\Ant\dept\CorporateDevelopment\BizDev\In-Shipment\ISO\zz_File_Location\macrotracking.txt"
Dim recordFile As Workbook
Set recordFile = Workbooks.Open(Filename:=strFilename)
Dim LastRow As Long
LastRow = recordFile.Sheets("macrotracking").Range("A1").SpecialCells(xlCellTypeLastCell).Row
wb.Activate
For i = 1 To Worksheets.Count
If Worksheets(i).Name = "Performance" Then
exists = True
End If
Next i
If exists Then
Advertiser_Name = Sheets("Performance").Range("C3").Value
Else
Advertiser_Name = Sheets("Raw Data").Range("J2").Value
End If
MsgBox wb.Name & exists & Advertiser_Name
''''''these are the variables you want to track, just separate by '& ; &'
recordFile.Sheets("macrotracking").Range("A" & LastRow + 1).Value = Environ("USERNAME") & ";" & Format(Now(), "m/dd/yyyy") & ";" & Format(Now(), "hh:nn:ss") & ";" & ActiveSheet.Range("C3").Value & ";" & "TOTAL"
recordFile.Sheets("macrotracking").Range("A" & LastRow + 1).TextToColumns Destination:=Range("A" & LastRow + 1), DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, Semicolon:=True
recordFile.Save
recordFile.Close savechanges:=True
If Err <> 0 Then
Err.Clear
End If
On Error GoTo 0
'End Tracker'
I would greatly appreciate it if someone can help me learn how to hide all windows for this entire macro.
I am building a macro based spreadsheet to transfer inputted data to another sheet labeled "data". Im only getting a runtime error 1004 when I click on the cmbSave_Click() button. I feel the issue is with my line of code being "iRow = Sheets("Data").Range("A40").End.Row + 1", but I am not sure. Im still trying to learn excel VBA.
I have tried debugging the code and also tried commenting code to try to come up with a solution.
Private Sub cmbSave_Click()
Application.ScreenUpdating = True
Dim iRow As Long
iRow = Sheets("Data").Range("A50").End(x1down).Row + 1
If ValidateForm = True Then
With ThisWorkbook.Sheets("Data")
.Range("A" & iRow).Value = iRow - 1
.Range("B" & iRow).Value = txtName.Value
.Range("C" & iRow).Value = txtScholar.Value
.Range("D" & iRow).Value = txtDate.Value
.Range("E" & iRow).Value = txtSession.Value
.Range("F" & iRow).Value = cmbReason.Text
.Range("G" & iRow).Value = txtComments.Value
End With
Call Reset
Else
Application.ScreenUpdating = True
Exit Sub
End If
Application.ScreenUpdating = True
Data should be able to input and save onto the other "data" sheet
I decided to learn VBA two weeks ago, and it's gone rather smooth. Now, however, I've encountered a problem I can't seem to solve on my own.
I've set up an excel document containing various modules. One of these modules extracts comments from a word document over to the excel sheet - which works as intended.
The problem is, I haven't been able to extract the first numbered header above each comment, which I'd very much like. Currently I have to do this manually after extracting the comments. As an example, I would like to also extract the first header and number above each comment, such as '2.1.1 Title'. If the comment is highlighting the header itself, it should be that header which is extracted as well.
I've tried a variety of things based on what I could find online, but every time I'm met with a variety of bugs I can't seem to fix. I've yet to find something that even sorta works. I did try one method which apparently should work in Word VBA, but I couldn't get it working within Excel.
Does anyone know how I would go about extracting the numbered headers? Any hints or tips will be greatly appreciated.
This is the code I have for the module:
Sub ImportCommentsDOCX()
Dim wdDoc As Object
Dim wdFileName As Variant
Dim i As Integer
wdFileName = Application.GetOpenFilename("Word files (*.docx),*.docx", , _
"Browse for file to be imported")
If wdFileName = False Then Exit Sub '(user cancelled import file browser)
Set wdDoc = GetObject(wdFileName) 'open Word file
'1: if no comments'
With wdDoc
If wdDoc.Comments.Count = 0 Then
MsgBox ("No comments")
End If
'2; Set excel headers'
Range("B" & 1).Value = "Number"
Range("B" & 1).Font.Bold = True
Range("C" & 1).Value = "Comment"
Range("C" & 1).Font.Bold = True
Range("D" & 1).Value = "Highlighted text"
Range("D" & 1).Font.Bold = True
Range("E" & 1).Value = "Initials"
Range("B" & 1).Font.Bold = True
Range("F" & 1).Value = "Date (*Imprecise)"
Range("F" & 1).Font.Bold = True
'3: Extract comments and meta data'
For i = 1 To wdDoc.Comments.Count
Range("B" & 1 + i).Value = wdDoc.Comments(i).Index
Range("C" & 1 + i).Value = wdDoc.Comments(i).Range
Range("D" & 1 + i).Value = wdDoc.Comments(i).Scope.FormattedText
Range("E" & 1 + i).Value = wdDoc.Comments(i).Initial
Range("F" & 1 + i).Value = Format(wdDoc.Comments(i).Date, "dd/MM/yyyy") 'Unreliable: Sometimes gives wrong date'
'Range("G" & 3 + i).Value = wdDoc.Comments(i).Range.ListFormat.ListString 'Returns empty'
Next i
End With
Set wdDoc = Nothing
MsgBox ("Extraction has completed")
End Sub
Here is your code with some adjustments:
Sub ImportCommentsDOCX()
Dim wdDoc As Object
Dim wdFileName As Variant
Dim i As Integer
wdFileName = Application.GetOpenFilename("Word files (*.docx),*.docx", , _
"Browse for file to be imported")
If wdFileName = False Then Exit Sub '(user cancelled import file browser)
Set wdDoc = GetObject(wdFileName) 'open Word file
'1: if no comments'
With wdDoc
wdDoc.Activate ' Added
If wdDoc.Comments.Count = 0 Then
MsgBox ("No comments")
End If
'2; Set excel headers'
Range("B" & 1).Value = "Number"
Range("B" & 1).Font.Bold = True
Range("C" & 1).Value = "Comment"
Range("C" & 1).Font.Bold = True
Range("D" & 1).Value = "Highlighted text"
Range("D" & 1).Font.Bold = True
Range("E" & 1).Value = "Initials"
Range("E" & 1).Font.Bold = True ' Modified
Range("F" & 1).Value = "Date (*Imprecise)"
Range("F" & 1).Font.Bold = True
'3: Extract comments and meta data'
For i = 1 To wdDoc.Comments.Count
Range("B" & 1 + i).Value = wdDoc.Comments(i).Index
Range("C" & 1 + i).Value = wdDoc.Comments(i).Range
Range("D" & 1 + i).Value = wdDoc.Comments(i).Scope.FormattedText
Range("E" & 1 + i).Value = wdDoc.Comments(i).Initial
Range("F" & 1 + i).Value = Format(wdDoc.Comments(i).Date, "dd/MM/yyyy") 'Unreliable: Sometimes gives wrong date'
'Range("G" & 1 + i).Value = wdDoc.Comments(i).Scope.ListFormat.ListString 'Returns empty' ' Modified ' Updated
Dim wp As Word.Paragraph: Set wp = wdDoc.Comments(i).Scope.Paragraphs(1) ' Updated
Do While wp.Range.ListFormat.ListString = "" ' Updated
Set wp = wp.Previous ' Updated
Loop ' Updated
Range("G" & 1 + i).Value = wp.Range.ListFormat.ListString ' Updated
Next i
End With
Set wdDoc = Nothing
MsgBox ("Extraction has completed")
End Sub
Please note my comments: Added and Modified
wdDoc.Activate was required at least on my computer, otherwise the
Range property is empty.
After initials a wrong column was bolded
The original text is referred to by the Range property, not the Scope (which is the content of the comment), so its ListFormat property should be used
The row index was not correct (3 instead of 1)
Looks working for me:
This requires Microsoft VBScript Regular Expression 5.5
Sub commentaires()
Dim regexOne As Object
Set regexOne = New RegExp
regexOne.Pattern = "^\d+\."
Dim s As String, s1 As String
Dim cmt As Word.Comment
Dim doc As Word.Document
For Each cmt In ActiveDocument.Comments
Dim wp As Word.Paragraph
Set wp = cmt.Scope.Paragraphs(1) ' Updated
Do While Not regexOne.Test(wp.Range.ListFormat.ListString)
Set wp = wp.Previous ' Updated
Loop ' Updated
s = s & _
wp.Range.ListFormat.ListString & ";" & _
cmt.Reference.Information(wdActiveEndAdjustedPageNumber) & ";""" & _
cmt.Scope & """;""" & _
cmt.Range.Text & """ " & vbCr
Next
Dim f As Integer
f = FreeFile
Open "c:\comments.csv" For Output As #f
Print #f, s
Close #f
End Sub
I am trying to work on a code that would enable me to copy data from the raw file and update the individual sheets in the master workbook for each value in column A of raw file.
Background: There are many unique IDs mentioned in column A of the raw file, other columns contain corresponding data to each unique id. Each unique ID has a separate sheet in the master workbook.
Requirement:
Remove unwanted unique ids mentioned in the to be removed sheet in raw file
Copy the entire row from the raw file, locate the relevant unique ID sheet in the master workbook and paste the data in the last row.
In case the unique id sheet is not there in the master workbook then to create it and paste the data.
Problem:
The code that I have gets stuck on locating the correct sheet in the master, it is unable to locate the sheet and when it goes to create a new sheet with the name it gives the error that the sheet name already exists.
In case there is a requirement to create a new sheet for a unique id, it should continue looping and paste data for other ids as well.
It should give a message box in the end giving details of all new sheets that were created.
Please help me out....I have been trying to solve this for a while now.
Raw file (Excel):
Master File (Excel):
Sheet names in Master File:
Code:
Sub unique_ids()
Dim NewFN As String, MasterFN As String
Dim lrow As Long, i As Long, drow As Long, j as Long
Dim rngf As Range, rngv As Range
Dim SName As Variant
Dim FoundDup As Range
'Open the Master file
proceed:
MasterFN = Application.GetOpenFilename(FileFilter:="All files (*.*), *.*", Title:="Please open the Master File")
If MasterFN = "" Then
MsgBox "You have not selected a file."
GoTo proceed
Else
Workbooks.Open Filename:=MasterFN
End If
MasterFN = ActiveWorkbook.Name
'Open the raw file
proceed1:
NewFN = Application.GetOpenFilename(FileFilter:="All files (*.*), *.*", Title:="Please open the raw File")
If NewFN = "" Then
MsgBox "You have not selected a file."
GoTo proceed1
Else
Workbooks.Open Filename:=NewFN
End If
'Save backup file
ActiveWorkbook.SaveAs Filename:="D:\Counts-" & Format(Date, "dd-mmm-yy") & ".xlsx", FileFormat:= _
xlOpenXMLWorkbook, CreateBackup:=False
Workbooks("Counts-" & Format(Date, "dd-mmm-yy") & ".xlsx").Close
Workbooks.Open Filename:=NewFN
NewFN = ActiveWorkbook.Name
'Delete the "to be removed" IDs
Sheets("counts").Select
For Row = Range("A65536").End(xlUp).Row To 2 Step -1
Set FoundDup = Sheets("To be deleted").Range("A:A").Find(Cells(Row, 1), LookIn:=xlValues, lookat:=xlWhole)
If Not FoundDup Is Nothing Then
Cells(Row, 1).EntireRow.Delete
End If
Next Row
‘Update Data
For j = 2 To lrow
SName = Workbooks(NewFN).Worksheets("counts").Range("K" & j).Value
On Error GoTo new_tab
Workbooks(NewFN).Worksheets("Counts").Range("A" & j & ":I" & j).Copy Workbooks(MasterFN).Worksheets(SName).Range("B" & Rows.Count).End(xlUp).Offset(1, 0)
Workbooks(MasterFN).Worksheets(SName).Range("A" & Rows.Count).End(xlUp).Value = Format(Date, "dd-mmm-yy")
drow = Workbooks(MasterFN).Worksheets(SName).Range("K" & Rows.Count).End(xlUp).Offset(-1, 0).Row
Workbooks(MasterFN).Worksheets(SName).Range("K" & drow - 1 & ":S" & drow - 1).Copy Workbooks(MasterFN).Worksheets(SName).Range("K" & drow & ":S" & drow)
Next j
new_tab:
MsgBox "New ID encountered", vbCritical
Workbooks(MasterFN).Sheets.Add(after:=Workbooks(MasterFN).Sheets(Worksheets.Count)).Name = SName
Workbooks(NewFN).Worksheets("counts").Range("A" & j & ":I" & j).Copy Workbooks(MasterFN).Worksheets(SName).Range("B" & Rows.Count).End(xlUp)
Workbooks(MasterFN).Worksheets(SName).Range("A" & Rows.Count).End(xlUp).Value = Format(Date, "dd-mmm-yy")
drow = Workbooks(MasterFN).Worksheets(SName).Range("K" & Rows.Count).End(xlUp)
Workbooks(MasterFN).Worksheets(SName).Range("K" & drow - 1 & ":S" & drow - 1).Copy Workbooks(MasterFN).Worksheets(SName).Range("K" & drow & ":S" & drow)
MsgBox "This work is now complete, new sheet added - " & SName
End Sub
The first potential problem I can see here is in the For j = 2 To lrow loop you keep referring to the variable i instead of what I assume is supposed to be j. I can't see that the i variable has been initialized anywhere?