Update named cell values - excel

I have a workbook with many named cells in different worksheets. I'm trying to write a VBA script that will read an external .csv file to extract a variable name and variable value, so that I can update the named cell values in my workbook.
I'm able to read and loop through the data in the CSV file but I am unable to update the named values.
Ideally, the script would check the variable name is a valid named cell in the workbook then update with the new value as defined in the .csv file.
I've run a number of iterations but the gist of the code is:
Public Sub readCSV()
'
' VBA script to read external CSV file
'
'
Dim filePath As String
Dim inFilePath As String
Dim inCase As String
strWorkBook = ActiveWorkbook.Name
filePath = Range("aString").Value
tmpsep = InStrRev(filePath, "\")
inCase = Right(filePath, Len(filePath) - tmpsep)
inFilePath = Left(filePath, Len(filePath) - Len(inCase))
' Check that path is valid and exit if not
Range("aString").Select
If IsEmpty(ActiveCell.Value) Then
MsgBox "ERROR! No Input File Defined - Exiting!"
Range("H7").Select
End
End If
' Open data file
Workbooks.Open Filename:=filePath
' Loop through variable names in input file
varNamCol = "C"
varColNum = "D"
' Ensure we're in input file
Windows(inCase).Activate
' Find last row input file - Call separate routine (working)
Call FindLastRow.FindLastRow(lRow)
i = 1
imax = lRow
Do While i <= imax
Windows(inCase).Activate
' Read Variable Name and Value from csv
inVarName = Range(varNamCol & I).Value
inVarValue = Range(varColNum & I).Value
If IsEmpty(inVarName) Then
MsgBox " Variable is empty - Moving On"
GoTo NextIteration
Else
Windows(strWorkBook).Activate
Range(inVarName).Value = inVarValue
End If
NextIteration:
i = i + 1
Loop
End Sub

Issue resolved by performing the operations the other way around. Instead of reading the input deck and trying to find the corresponding named range in the target workbook, I loop through the named ranges and find the corresponding values from the input deck.
I have also included the Application.EnableEvents commands to prevent embedded Worksheet_Change macros from activating while updating values.
The code is:
Sub tmp()
Dim filePath As String
Dim inFilePath As String
Dim inCase As String
On Error GoTo ErrorHandler
Application.ScreenUpdating = False
Application.EnableEvents = False
'----------------------------------
' Find path for input file
strWorkBook = ActiveWorkbook.Name
filePath = Range("aString").Value
tmpsep = InStrRev(filePath, "\")
' Input file workbook name
inCase = Right(filePath, Len(filePath) - tmpsep)
'Input file full path
inFilePath = Left(filePath, Len(filePath) - Len(inCase))
' Check that path is valid and exit if not
Range("aString").Select
If IsEmpty(ActiveCell.Value) Then
MsgBox "ERROR! No Input File Defined - Exiting!"
Range("H7").Select
End
End If
' Open input data file
Workbooks.Open Filename:=filePath
'-------------------------------------
Dim rFind As Range
' Process to update name values
Windows(strWorkBook).Activate
For Each nm In ActiveWorkbook.Names
varname = nm.Name
varsheet = Range(nm).Parent.Name
varcell = nm.RefersToRange.Address(False, False)
Sheets(varsheet).Select
Range(varcell).Select
' Ensure variable in Home and HiddenVariables are not over-written
If varsheet = "Home" Or varsheet = "HiddenVariables" Then
GoTo NextIteration
End If
' Omit non-user input variables cbelts, anrz, anumhxc, nrotzone
If varname = "cbelts" Or varname = "anrz" Or varname = "anumhxc" Or varname = "nrotzone" Then
GoTo NextIteration
End If
' Selection.ClearContents
Windows(inCase).Activate
' Find range in inCase that matched varName
With Range("C:C")
Set rFind = .Find(What:=varname, LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False)
If Not rFind Is Nothing Then
inCaseRow = rFind.Row
updateVal = Range("D" & inCaseRow).Value
Windows(strWorkBook).Activate
Sheets(varsheet).Select
Range(varcell).Value = updateVal
Range("D4").Select
Else
Windows(strWorkBook).Activate
Range("D4").Select
End If
End With
NextIteration:
Next nm
' Include routines to populate Porous Media inputs
Application.ScreenUpdating = True
' Close input case file
Windows(inCase).Activate
ActiveWindow.Close
ErrorHandler:
Application.EnableEvents = True
End Sub

Related

Export to Text without Quotation Marks

I have multiple worksheets in my workbook.
Each worksheet has two columns of data (ColA and ColC) which I want to print to separate text files.
The attached code results in two text files: “WorksheetTab_LnFn.txt” and “WorksheetTab_FnLn.txt”
The text file saved from my ColA does NOT quotations whilst the second text file saved from my ColC DOES HAVE quotation marks - I want each resulting text file to NOT have quotation marks.
I may have worksheets later with data in ColA, ColC, ColE and ColG, each of which I want to export/save/print to a text file – thus I would want in that case four separate text document, all WITHOUT quotation marks.
The best code I have been able to find is locate is: Write export of selected cells as a .txt file without "quotation marks" and I have looked at How to create a text file using excel VBA without having double quotation marks?.
I understand most of it, but am not being successful at integrating parts of this code into mine. Ideally I am seeking to reduce the code and loop so it would process ColA and then ColB without having two separate code blocks. I did use code I found and made minimal changes, but do not know if the Case LCase line is necessary
'Create FirstName LastName Isolation TXT files
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each sh In Sheets
Select Case LCase(sh.Name)
Case LCase("[COLOR=#0000ff]Master[/COLOR]"), LCase("[COLOR=#0000ff]Info[/COLOR]")
Case Else
sh.Range("A:A").Copy
Workbooks.Add
ActiveSheet.Paste
ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & "\" & sh.Name & "_FnLn.txt", _
FileFormat:=xlTextMSDOS, CreateBackup:=False
ActiveWorkbook.Close False
End Select
Next
'Create LastName FirstName Isolation TXT files
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each sh In Sheets
Select Case LCase(sh.Name)
Case LCase("[COLOR=#0000ff]Master[/COLOR]"), LCase("[COLOR=#0000ff]Info[/COLOR]")
Case Else
sh.Range("C:C").Copy
Workbooks.Add
ActiveSheet.Paste
ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & "\" & sh.Name & "_LnFn.txt", _
FileFormat:=xlTextMSDOS, CreateBackup:=False
ActiveWorkbook.Close False
End Select
Next
MsgBox "Text Files Created"
End Sub
This should do what you want:
Sub Tester()
Dim filename As String, myrng As Range, sh As Worksheet, wb As Workbook
Set wb = ThisWorkbook
For Each sh In wb.Worksheets
filename = wb.Path & "\" & sh.Name & "_FnLn.txt"
Set myrng = sh.Range("C1:C" & sh.Cells(sh.Rows.Count, "C").End(xlUp).Row) 'use sh reference
RangeToTextFile myrng, filename 'comma-separated
'RangeToTextFile myrng, filename, vbtab 'e.g. for tab-separated file
Next
MsgBox "Text Files Created"
End Sub
'write a range `rng` to a text file at `fPath`. Default separator is comma
Sub RangeToTextFile(rng As Range, fPath As String, Optional separator As String = ",")
Dim data, r As Long, c As Long, sep, lo As String, ff As Integer
ff = FreeFile() 'safer than using hard-coded #1
Open fPath For Output As #ff
If rng.Cells.CountLarge = 1 Then
ReDim data(1 To 1, 1 To 1) 'handle special case of single cell
data(1, 1) = rng.Value
Else
data = rng.Value 'get all values as an array
End If
For r = 1 To UBound(data, 1) 'loop rows
lo = "" 'clear line output
sep = "" 'clear separator
For c = 1 To UBound(data, 2) 'loop columns
lo = lo & sep & data(r, c) 'build the line to be written
sep = separator 'add separator after first value
Next c
Print #ff, lo 'write the line
Next r
Close #ff
End Sub

How to use multiple for each loops simultaneously?

Below code is used to run a macro that takes multiple variables and loops through the range to fill them into another sheet and then save as a pdf.
With 1 for each loop it works perfectly, but when I try to use 2; it will run through the first loop once and then loop through the second loop only.
Any ideas to fix this?
Sub CommandButton2_Click()
For Each c In Sheets("Resultaten").Range("N2:N1000").Cells '//Variable 1 range
If c = "" Then Exit For '//To end the loop when cells are empty
Sheets("Invuldocument").Range("B5").Value = c.Value '//Variable 1 transfer
For Each w In Sheets("Resultaten").Range("W2:W1000").Cells '//Variable 2 range
If w = "" Then Exit For '//To end the loop when cells are empty
Sheets("Invuldocument").Range("J5").Value = w.Value '//Variable 2 transfer
Application.Wait Now + #12:00:01 AM# ' //timer if the pc cannot handle the speed
Dim FileName As String '//Code below is to save as PDF in every loop
Dim Path As String
Application.DisplayAlerts = False
Path = "C:\Users\802435\Desktop\test12\"
FileName = "PRO-" & Range("B5").Value & "-" & Range("D41").Value & ".pdf"
ActiveWorkbook.SaveAs Path & FileName, xlOpenXMLWorkbook
Application.DisplayAlerts = True
Next '//Repeat for every Variable in the list until Exit For
Next '//No idea why i need this
End Sub
The idea is to loop through the row number then do a check if the value in both column N and W exist, if it does then it will copy the value to the 2 cells Invuldocument worksheet.
Sub CommandButton2_Click()
Const Path As String = "C:\Users\802435\Desktop\test12\" 'Assuming that the path don't change, you can declare it as a constant variable
Dim resultWS As Worksheet
Set resultWS = ActiveWorkbook.Worksheets("Resultaten")
Dim invulWS As Worksheet
Set invulWS = ActiveWorkbook.Worksheets("Invuldocument")
Dim i As Long
For i = 2 To 1000
If resultWS.Cells(i, "N").Value <> "" And resultWS.Cells(i, "W").Value <> "" Then
invulWS.Cells(5, "B").Value = resultWS.Cells(i, "N").Value
invulWS.Cells(5, "J").Value = resultWS.Cells(i, "W").Value
Dim FileName As String '//Code below is to save as PDF in every loop
Application.DisplayAlerts = False
FileName = "PRO-" & Range("B5").Value & "-" & Range("D41").Value & ".pdf"
ActiveWorkbook.SaveAs Path & FileName, xlOpenXMLWorkbook
Application.DisplayAlerts = True
Else
Exit For
End If
Next i
End Sub
Note: I did not test if the code for "saving as PDF" works as it is out of this question's scope. You are definitely encouraged to fully qualify your range reference in the code that assign FileName as it is currently referring to ActiveSheet which might not be what you want.

Selecting A worksheet by name, I have the name as string

I have a VBA code that copies a template sheet and renames it.
I have the new name saved as a public string:
"My_Tamplate" is the sheet I copy from. "PublicStringName" is the public string variable I use to rename it to.
I also use the "PublicStringName" in other places in the form, this is why I needed it as a string.
Sheets("My_Tamplate").Copy After:=Worksheets(Sheets.Count)
ActiveSheet.name = PublicStringName
Next when I need to write the data I collected using a form, I want to write it to the newly created sheet.
Next I open a new form, collect data from the user to several variables.
Now I want to write the data into the newly created sheet (now named "PublicStringName"). If I declare WS as worksheet, it will not accept "PublicStringName" as it is a string (I think).
I do not know what sheet number it will be so I cannot call it by (sheet1) for example.
I don't know how to upload my example excel, so:
The Excel has 2 sheets named: Data (sheet2) and Project_Template (Sheet1). In sheet2 C3 I have =MAX(B:B).
I have 1 form (UserForm1), it has a multi page object.
In page 1 I have a text box txtProjectName and a button cmdCreateProject.
In page 2 I have 5 text boxes, named: txtData1 to txtData5 and an Update button btnUpdate.
I tried PeterT's solution (here in the code). Attaching the problematic code here:
Public ProjectName
Private Sub btnUpdate_Click()
Dim WS As Worksheet
Dim Addme As Range
Set WS = ThisWorksheet.Sheets(ProjectName)
Set Addme = WS.Cells(Rows.Count, 3).End(xlUp)
With WS
Addme.Offset(0, 1).Value = Me.txtData1
Addme.Offset(0, 2).Value = Me.txtData2
Addme.Offset(0, 3).Value = Me.txtData3
Addme.Offset(0, 4).Value = Me.txtData4
Addme.Offset(0, 5).Value = Me.txtData5
End With
MsgBox "Contact for Project:" & " " & ProjectName & ", " & "was successfully
added"
End Sub
Private Sub cmdCreateProject_Click()
Dim path As String
Dim mydir As String
Dim DataSh As Worksheet
Set DataSh = Sheet2
ProjectName = ""
'error handler
On Error GoTo errHandler:
ProjectName = Me.txtProjectName.Value
If Me.txtProjectName.Value = "" Then
MsgBox "Please enter a Project Name", vbOKOnly, "Project Name Error"
Exit Sub
End If
mydir = ThisWorkbook.path & "\" & ProjectName
If Dir(mydir, vbDirectory) = "" Then
MkDir mydir
'Copy tamplate sheet to for new Project
Sheets("Project_Template").Copy After:=Worksheets(Sheets.Count)
ActiveSheet.Name = ProjectName
Else
MsgBox "Directory already exsists"
Me.txtProjectName.Value = ""
Me.txtProjectName.SetFocus
ProjectName = ""
Exit Sub
End If
Set Addme = DataSh.Cells(Rows.Count, 3).End(xlUp).Offset(1, 0)
DataSh.Activate
DataSh.Select
With DataSh
'add the unique reference ID then all other values
Addme.Offset(0, -1) = DataSh.Range("C3").Value + 1
Addme.Value = Me.txtProjectName
End With
Me.MultiPage1.Pages(1).Enabled = True
Me.MultiPage1.Pages(1).Visible = True
Me.MultiPage1.Pages(0).Enabled = Fals
Me.MultiPage1.Pages(0).Visible = Fals
Exit Sub
errHandler:
'if error occurs then show me exactly where the error occurs
MsgBox "Error " & Err.Number & _
" (" & Err.Description & ")in procedure PcmdClear_Click of Form ProjectDB"
End Sub
Now when I try to update the newly created Worksheet (named after the project) I get the error:
Run-time error '424':
Object required
On the line:
Set WS = ThisWorksheet.Sheets(ProjectName)
I think that Gary's Student answer is missing the step where after I create the new sheet I start collecting the data.
Here is one way to use the Name:
Sub FreshSheet()
Dim PublicStringNAme As String
PublicStringNAme = "Ellan"
Sheets("My_Tamplate").Copy After:=Worksheets(Sheets.Count)
ActiveSheet.Name = PublicStringNAme
'
'
'
'
Sheets(PublicStringNAme).Range("A1") = 1
End Sub
If you want to make the variable "more Global" then:
Public PublicStringName As String
Sub FreshSheet()
PublicStringName = "Ellan"
Sheets("My_Tamplate").Copy After:=Worksheets(Sheets.Count)
ActiveSheet.Name = PublicStringName
'
'
'
'
Sheets(PublicStringName).Range("A1") = 1
End Sub
See:
Scope

how to select a specific cells range dynamically in excel vba?

I've a scenario in which i'm copying data from multiple files to master files, I want when the program run at first time it should start pasting the data at my specified range in the master file which is working fine. But when the program is run again it's not going to start from the previous range rather it's start pasting data below at the previous record which is duplication of the same data, I want that when user first time or as many time run the program program range start at the same location where it was at first time running.
Following is my code.
Sub Append()
'Append data from other files
Path = "E:\NPM PahseIII\"
Dim c As Range
'find the second empty cell in ColA
Set c = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(2, 0)
'target range for pasting data it first run this is actually pointing to
'my desire range but at second or multiple running the range is starting
'below at the previous record
Set targetcellL = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(2, 1)
Set targetcellR = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(5, 4)
Filename = Dir(Path & "*.xlsx")
Do While Filename <> ""
If InStr(Filename, ".") > 0 Then
Filenamenoext = Left(Filename, InStr(Filename, ".") - 1)
End If
c.Value = Filenamenoext
Set c = c.Offset(4, 0)
Set wb = Workbooks.Open(Filename:=Path & Filename, ReadOnly:=True)
Data = wb.Worksheets(1).Range("B3:E6").Value
wb.Worksheets(1).Range("B3:E6").Copy
ThisWorkbook.Activate
ActiveSheet.Range(targetcellL, targetcellR).Select
ActiveSheet.Paste
Set targetcellL = targetcellL.Offset(4, 0)
Set targetcellR = targetcellR.Offset(5, 0)
Workbooks(Filename).Close
Filename = Dir()
Loop
End Sub
Problem: I want that when the program as run as many time it should start pasting Data it the Range where it is pasting data for the first time.
Following images will clear my problem more precisely.
When the program run for the first time i get pasted data it below range which is what i want.
When Run for the 2nd time i get data it below range
what should i do to make the behavior as such that when the program run for as many time the data should paste at the range where it's at first run see pic.
Here are two different ways to do it:
Sub AppendValuesAndFormats()
'Append data from other files
Const Path = "E:\NPM PahseIII\"
Dim target As Range
With ThisWorkbook.ActiveSheet
.UsedRange.Offset(2).ClearContents
Set target = .Range("A3")
End With
Filename = Dir(Path & "*.xlsx")
Do While Filename <> ""
With Workbooks.Open(Filename:=Path & Filename, ReadOnly:=True)
target.Value = IIf(InStr(Filename, ".") > 0, Left(Filename, InStr(Filename, ".") - 1), "")
.Worksheets(1).Range("B3:E6").Copy Destination:=target.Offset(0, 1)
.Close SaveChanges:=False
End With
Set target = target.Offset(4)
Filename = Dir()
Loop
End Sub
Sub AppendValues()
'Append data from other files
Const Path = "E:\NPM PahseIII\"
Dim target As Range
With ThisWorkbook.ActiveSheet
.UsedRange.Offset(2).ClearContents
Set target = .Range("A3")
End With
Filename = Dir(Path & "*.xlsx")
Do While Filename <> ""
With Workbooks.Open(Filename:=Path & Filename, ReadOnly:=True)
target.Value = IIf(InStr(Filename, ".") > 0, Left(Filename, InStr(Filename, ".") - 1), "")
target.Range("B1:E4").Value = .Worksheets(1).Range("B3:E6").Value
.Close SaveChanges:=False
End With
Set target = target.Offset(4)
Filename = Dir()
Loop
End Sub

object required run time error '424'

i am getting object required run time error in below code at line , i checked sheet names they are correct but still showing same error Sheet1.Range("A1").Value = Date & " " & Time
Private Sub CommandButton1_Click()
Dim username As String
Dim password As String
username = TextBox1.Text
password = TextBox2.Text
Dim info
info = IsWorkBookOpen("D:\TMS_Project\username-password.xlsx")
If info = False Then
Workbooks.Open ("D:\TMS_Project\username-password.xlsx")
End If
Dim x As Integer
x = 2
Do While Cells(x, 1).Value <> ""
If Cells(x, 1).Value = username And Cells(x, 2).Value = password Then
MsgBox "Welcome!"
Sheet1.Range("A1").Value = Date & " " & Time
Selection.NumberFormat = "m/d/yyyy h:mm AM/PM"
UserForm1.Hide
ActiveWorkbook.Close True
End
Else
x = x + 1
End If
Loop
MsgBox "Please check your username or password!"
ActiveWorkbook.Close True
TextBox1.Text = ""
TextBox2.Text = ""
TextBox1.SetFocus
End Sub
When you use Sheet1.Range("A1").Value, Sheet1 is actually the Worksheet.CodeName property, read here on MSDN.
While I think you meant to use the worksheet, which name is "Sheet1", then you need to use Worksheets("Sheet1").Range("A1").Value.
If you would have defined and set your Worksheet object, you would have been able to track it.
I am using the piece of code below, to verify that no one has changed my sheet's name (or deleted it).
Option Explicit
' list of worksheet names inside Workbook - easy to modify here later
Const ShtName As String = "Sheet1"
'====================================================================
Sub VerifySheetObject()
Dim Sht As Worksheet
On Error Resume Next
Set Sht = ThisWorkbook.Worksheets(ShtName)
On Error GoTo 0
If Sht Is Nothing Then ' in case someone renamed the Sheet (or it doesn't exist)
MsgBox "Sheet has been renamed, it should be " & Chr(34) & ShtName & Chr(34), vbCritical
Exit Sub
End If
' your line here
Sht.Range("A1").Value = Date & " " & Time
End Sub
To use Variables for your Sheets use:
Dim sht as Worksheet
Set sht = Worksheets("Name")
If you are refering a lot to worksheets its a must to use, but also makes it much easier to change later on.

Resources