I have a cell that is named DATA_FIELD_NAME and I would like to use it in the following way:
Private Sub LockCells(iNumberOfDataColumns As Long)
ActiveSheet.Unprotect
ActiveSheet.Cells.Locked = False
ActiveSheet.Range("DATA_FIELD_NAME:DATA_FIELD_NAME+iNumberOfDataColumns").Locked = True
ActiveSheet.Protect Contents:=True
End Sub
Essentially I would like to lock the range of cells starting from the DATA_FIELD_NAME cell horizontally to DATA_FIELD_NAME + n.
However this doesn't work. Could someone please tell me the correct syntax or an alternate method?
I'd try this:
ActiveSheet.Range("DATA_FIELD_NAME").Resize(1, iNumberOfDataColumns).Locked = True
Here is a reference on Range.Resize Basically it changes the amount of cells you are dealing with based upon the current range. In what I gave you, it changes to 1 row, and iNumberOfDataColumns columns.
I just wrote this in SO, not tested in XL, so it might contain typos, but this should work:
With ActiveSheet
Range(.Range("DATA_FIELD_NAME"), .Range("DATA_FIELD_NAME").Offset(0,iNumberOfDataColumns)
End With
The idea is to combine Offset(rows, cols) with to use the Range(range1, range2) syntax.
Alternatively, you could be a dynamic range name as explained here.
Related
I'm trying to make a button which on click will print out the value of a cell as a string and not the appearance of the cell itself (if that makes sense) using the .PrintOut method in VBA. That cell is the active cell, whose value I set based on the cell next to it. Here is my code:
Sub Graphic2_Click()
Dim MyNumber as Integer
MyNumber = ActiveCell.Offset(-1, 0) + 1
ActiveCell.Value = MyNumber
ActiveCell.Printout
End Sub
I also tried MyNumber.PrintOut but I get an "Invalid Qualifier" error.
Am I missing out something too simple?
Please, try the next code. It use a temporary 'helper cell' where the format to be pasted (and recuperated after printing out):
Sub Graphic2_Click()
Dim helperCell As Range
With ActiveCell
.value = CLng(Offset(-1, 0)) + 1
Set helperCell = .Offset(1) 'it may be any cell to temporarilly be used
.Copy
helperCell.PasteSpecial xlPasteFormats
.ClearFormats
.PrintOut
helperCell.Copy
.PasteSpecial xlPasteFormats: helperCell.ClearFormats
End With
End Sub
To literally print just the contents of the cell:
Clear number formatting for the specified cell
Autofit column width for that column
Turn off gridlines
Turn off row and column headings
Set print area to the single cell, dismissing any warnings
Print out the active sheet
Each of these are straightforward to do in VBA, and probably straightforward to research on SO anyway.
You may also consider a mechanism to return the changed settings to their initial states afterwards. This would involve pushing (storing) the initial state to a variable or variables first, and popping (restoring) it back afterwards.
Explanation:
The VBA method .PrintOut is something you do to a worksheet, not a cell or its contents. Therefore, to get what you need, you need to set up the worksheet for printing so that the only thing that will appear is the contents of your chosen cell. This is what the above steps do.
For more information about the .PrintOut method, see:
https://learn.microsoft.com/en-us/office/vba/api/excel.sheets.printout
Or, to continue what the OP tried:
You could try something like:
ActiveCell.Formula = Range(ActiveCell.Offset(-1,0)).Value2 + 1
If this does not work, try:
ActiveCell.Formula = Range(ActiveCell.Offset(-1,0).Address).Value2 + 1
Or try these without the + 1 on the end, to verify that the rest of the formula is working the way you want it too. As mentioned, you may get a type mismatch issue causing an error if you don't trap first for whether the referenced cell contains a number.
.Formula in this example is how I am setting the content of the cell, and it can be used even when setting a value not necessarily literally a formula. You could use Value instead if you prefer.
.Value2 is a robust method of extracting the evaluated content of the source cell, as a value instead of as a formula.
The PrintOut method is to print a worksheet, not a range or single cell.
Note: This answer is not tested, as I am not near Excel right now.
Also... it's possible that there could be much simpler ways to do what you are trying to accomplish. Could you provide a bit more detail about the context of what you are trying to do.
I'd like to modify values on specific cells depending on a specific group if it's expanded or collapsed.
I found a way, but it's a manual way (image1 image2) (the macro needs to be launched on each run).
Is there a way to use a function (i.e. worksheet_change), so that will be on real time ?
P.S. Sorry for my bad English and be kind, I'm kinda new on VBA (first code).
Thank you.
Private Sub groups()
If Worksheets("Feuil1").Columns("F").ShowDetail = True Then
Range("K2:K7").Value = "YES"
Else
Range("K2:K7").Value = "NO"
End If
End Sub
Thank you Luuklag for your solution, but as I said in my comment, in your code I have to update manually the placeholder cell which is not what I'm looking for.
But, I found something where my cells get updated by expanding or collapsing my group. And for this, as you said, I need a placeholder cell that gets updated on each calculation.
I use the formula =NOW on cell A1, because it's always useful to know the time and date.
Here is the (combined) code, for those who are looking a solution :
Private Sub Worksheet_Calculate()
Application.EnableEvents = False
'Where F is the column having the group button
If Columns("F").ShowDetail = True Then
'This is where you choose the cells that are dependent to the group and attribute something
Range("G10:G19").Value = "YES"
Else
'Same here. It could be other cells too
Range("G10:G19").Value = "NO"
End If
Application.EnableEvents = True
End Sub
There is a simple solution to this. Every time you expand or collapse a group you trigger the worksheet_calculate event. This can be used to your advantage.
All you need is a placeholder cell, which you populate with a volatile function (a function that changes its value on each calculation). You can use =randbetween(1,10) or =NOW() for example.
You then have your worksheet change event to look for your placeholder cell, AA1 in this example.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("AA1")) Is Nothing Then
Call groups
End If
End Sub
I have an excel sheet with 1,373,760 used cells and each of them have a formula inside it unique in their own way. But every cell refers to a file path, which needs to be changed. Search and replace is taking huge amount of time and fails often at certain places. Is there an efficient way to replace these cells?
Sample formulae: '\root\folder\subfolder\another_folder[workbook_name]worksheet_name'cellNumber
Workbook, Worksheet, cell number are unique. Only the path is constant.
I tried referring to other cells by storing path and sheet names, but it's not working that way:
Reference another workbook with dynamic worksheet name
All these cells are populated using VBA which took around 15 hours. So any efficient way to create the new workbook is appreciated as well.
Thanks in advance!!
Something like this, depending on what exactly you are looking for:
Public Sub TestMe()
Dim myCell As Range
For Each myCell In ActiveSheet.UsedRange
If myCell.HasFormula Then
If InStr(1, myCell, "\root\folder\subfolder\another_folder") Then
myCell.Formula = "=root\folder\subfolder\another_folder" + something
End If
End If
Next myCell
End Sub
Turning Off automatic calculations here is a good idea.
The code goes around each cell in the UsedRange of the ActiveSheet and in case that it is a formula, it checks whether it contains '\root\folder\subfolder\another_folder.
If this is the case, a new formula is generated.
Search and replace from my humble opinion is your fastest solution, disable calculations via VBA or manually. after the replace has finished enable automatic calculations.
VBA code to enable and disable automatic calculations:
Sub Disbale_Automatic_Calc()
Application.Calculation = xlCalculationManual
End Sub
Sub Enable_Automatic_Calc()
Application.Calculation = xlCalculationAutomatic
End Sub
I'm currently trying to write a macro based on sheet change, where the letters in a table column are automatically converted to upper case. So, for example, if I entered "abcde-12345-678" into a cell, it would automatically correct to "ABCDE-12345-678". After doing some digging, I found some code that has worked for some people, but I'm having trouble tweaking it to suit my needs.
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("E:E")) Is Nothing Then Exit Sub
Application.EnableEvents = False
Target = UCase(Target)
Application.EnableEvents = True
End Sub
There are two things that I would like to address. The first being, that this code isn't currently working for me. I have it in the correct location according to the author (located in the Sheet1 object). Are there any ideas as to why this isn't working?
The second is that I would like to modify the code to refer to a table column rather than a range. For example, I've tried changing the second line of the above code to the following (the name of my table is ReviewTracker, and the column I'm interested in is Product Number):
If Intersect(Target, Range(ReviewTracker[[#Headers],[Product Number]])) Is Nothing Then Exit Sub
This returned a compile error "Expected: list separator or )". So there is obviously something wrong with it, but hopefully it might help illustrate what it is I'm trying to accomplish.
Thanks in advance for any help on the issue.
-Sean
First. You can have events disabled due to lots of reason. Let's make it sure that events are on which you can do as follows:
go to VBA Editor >> open Immediate Window >> write there: Application.EnableEvents = true >> press Enter
Second. To check if intersection match appropriate column within you ListObject table you need something like this:
If Intersect(Target, Range("ReviewTracker[Product Number]")) is Nothing Then
assuming that ReviewTracker is table name and Product Number is table column. You don't need #Headersas it will refer only to header row.
What UCase does is converting all the characters in a given string into upper case and thus you can apply it to any Range.Value. Worksheet_Change is called every time the value of a cell has changed and thus is a good place to put your code. But the way you are using to refer the table is wrong. The code your posted adapted to your requirements:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Sheet1.ListObjects("Table1").ListColumns(1).Range) Is Nothing Then Exit Sub
Target.Value = UCase(Target.Value)
End Sub
It converts into upper caps any string input in the first column of Table1 in Sheet1. It has to be placed in the Sheet1 object file (in the VBA Project explorer: Sheet1 (Sheet1) inside the Microsoft Excel Object folder). Adapting it to your actual conditions is straightforward.
Very basic, and very annoying, I have searched solution for many hours with no help...
Problem: I'm populating Combobox from named range, range is list of times (formatted as time :-), Combo seems fine, drop-down shows my times as they should be, but when selected time is formatted as a decimal number...
Here is the code (ripped down to bare minimum):
Private Sub UserForm_Initialize()
ComboBoxTime.RowSource = "Help!Time"
End Sub
"Help" is name of worksheet containing named range "Time"I have tried formatting different ways with no luck...
ComboBoxTime = Format(ComboBoxTime, "hhmm")
Here is link to sample. http://www.equstom.fi/dateproblem.html
(And yes I need to populate from named range, instead for each loop, and I will set .value with code, Whole document is actually quite complex, but I included just The problem part...)
Try something like this:
Private Sub ComboBox1_Change()
With ComboBox1
.Value = Format(.Value, "hh:mm:ss AMPM")
End With
End Sub
HTH!
Edit
This is what I see when leaving your combo. The time display works OK.
Edit 2
Found the error "invalid property":
You must set "Match Requiered" to FALSE in the combo box. If you consider that it should be "TRUE" you will have to validate by hand ...
The problem is named range I'm using, when values are formatted as time it won't work. I got it to work if values were Text! Problem has something to do with excel being in Finnish and VBA in english...
I added second column next to range which copies text values to this named second range formatted as time. Quick and Dirty! (Thanks for your input Belisarius)