Writing formula into Excel through Access VBA - vba

I want to insert in "A1" some text "ABC" and the following cell in "B1" an if statement. However I get only the first entry "ABC" inserted and then an error at FormulaR1C2 "Object doesn't support this property or method". I'm not sure I'm using the R1C2 correctly. I was assuming it stood for Row 1 Column 2, can someone help me out.
Dim Excel_App As Object
Dim strExcel As String
Set Excel_App = CreateObject("Excel.Application")
Excel_App.Visible = True
Excel_App.Workbooks.Add
With Excel_App
.Range("A:B").EntireRow.ColumnWidth = 25
.Range("A2").EntireRow.Font.FontStyle = "Bold"
.ActiveCell.FormulaR1C1 = "ABC"
strExcel = "=IF(A1 = """"," & """EMPTY""" & "," & """FILLED""" & ") "
.ActiveCell.FormulaR1C2 = strExcel
End With

FormulaR1C1 is the method of how the formula is written.
Formula refers to writing a formula in A1 like =B1+C1.
To write that same formula using R1C1 notation, you would write =RC[1] + RC[2]. Furthermore to write =B2+C2 in A1 write this =R[1]C[1] + R[1]C[2] -> so you can see you are offsetting the columns and rows where you want the formula to return values from.
What you want to do in your code is offset the place where the formula will be placed, rather than how it's calculating, so you should write this:
.ActiveCell.Offset(,1).Formula = strExcel
Actually, you should get rid of ActiveCell altogether, unless you absolutely need it.
I would write your code like this for better, more accurate execution:
Dim Excel_App As Object
Dim strExcel As String
Dim wkb as Object, wks as Object
Set Excel_App = CreateObject("Excel.Application")
Excel_App.Visible = True
Set wkb = Excel_App.Workbooks.Add
Set wks = wkb.Sheets(1) 'assumes you want first sheet, can modify for sheet index or name
With wks
.Range("A:B").EntireRow.ColumnWidth = 25
'I think this will actually set every row to 25, is that what you want?
.Range("A2").EntireRow.Font.FontStyle = "Bold"
.Range("A1").Value = "ABC" 'don't need to write Value, but just to show you the property
strExcel = "=IF(A1 = """"," & """EMPTY""" & "," & """FILLED""" & ") "
.Range("B1").Formula = strExcel
End With

FormulaR1C1 is a property which returns the formula of a cell expressed in R1C1 formula style.
You need to reference cells by using the Workbook.WorkSheet.Range syntax.
So first you need to specify the workbook you are working in, which in your case is the workbook added by the statement Excel_App.Workbooks.Add. Your new workbook is automatically named something like "Book1" and automatically has the default number of worksheets added named "Sheet1" through "Sheetn" where n is the default number of sheets.
So you're final code to write to that line is
Excel_App.Workbooks(1).Worksheets("Sheet1").Cells(1, 1) = "ABC"
Excel_App.Workbooks(1).Worksheets("Sheet1").Cells(1, 2).Formula = "=IF(A1 = """"," & """EMPTY""" & "," & """FILLED""" & ")"

Related

Writing Excel data to Word content controls without error messages

This question is about using content controls to move data values from Excel to Word in VBA. Please note I have enabled the "Microsoft Word 16.0 Object Library" under references in the MSExcel VBA environment.
My project needs to send Excel data to specific places in a Word document.
PROBLEM: It seems I am not using the contentcontrols properly and keep getting runtime errors I'm not finding much information about. Either RTE-438
Object doesen't support this method
or RTE-424
Object Required
Description of what the code does: There are two baseline workbooks with multiple worksheets. Another analysis workbook uses each of these is programmed with VLOOKUP(INDIRECT...),) to generate tables for reports put into a word document. A Variant is used to change the tabs being sourced in the baseline workbook. The analysis is basically CATS-DOGS=PETS. on each cycle through, tables that are not informational (no difference between two baseline workbooks) are skipped and the next tab is analyzed. If a table is informative, then a PDF is produced. The report (a Word document) is updated. Table is added to the report. Upon completion, the next tab or evaluation table is considered.
Sub CommandButton1_Click()
Dim Tabs(0 To 18) As Variant
Tabs(0) = "01"
Tabs(1) = "02"
Tabs(2) = "03"
Tabs(3) = "03"
Tabs(4) = "04"
Tabs(5) = "05"
Tabs(6) = "06"
Tabs(7) = "07"
Tabs(8) = "08"
Tabs(9) = "09"
Tabs(10) = "10"
Tabs(11) = "11"
Tabs(12) = "12"
Tabs(13) = "13"
Tabs(14) = "14"
Tabs(15) = "15"
Tabs(16) = "16"
Tabs(17) = "17"
Tabs(18) = "18"
Dim xlApp As Object
On Error Resume Next
Set xlApp = GetObject("excel.applicaiton")
If Err.Number = 429 Then
Err.Clear
Set xlApp = CreateObject("excel.applicaiton")
End If
On Error GoTo 0
Dim controlThis As String ' the controlThis variable is to the address of the particular data unit that should be passed to a word.documents.contentcontrols to update the text in the word document based on the change in the actual data.
Dim NetworkLocation As String
NetworkLocation = "\\myServer\myFolder\mySubfolder\"
Dim CATS As String
CATS = "kittens.xlsx"
Excel.Application.Workbooks.Open FileName:=(NetworkLocation & "Other Subforder\ThisWway\" & CATS)
Dim DOGS As String
DOGS = "puppies.xlsx"
Excel.Application.Workbooks.Open FileName:=(NetworkLocation & "differentSubfolder\ThatWay\" & DOGS)
'Populates the array with analysis tables
Dim Temples As Object
Dim Template(3 To 9) As Variant
Template(3) = "\3\EVAL Table 3.xlsx"
Template(4) = "\4\EVAL Table 4.xlsx"
Template(5) = "\5\EVAL Table 5.xlsx"
Template(6) = "\6\EVAL Table 6.xlsx"
Template(7) = "\7\EVAL Table 7.xlsx"
Template(8) = "\8\EVAL Table 8.xlsx"
Template(9) = "\9\EVAL Table 9.xlsx"
Dim strXLname As String
Dim opener As Variant
For Each opener In Template
strXLname = NetworkLocation & "Other Subfolder\EVAL Tables\WonderPets" & opener
Excel.Application.Workbooks.Open FileName:=strXLname
Dim currentDiffernce As Long
currentDifference = ActiveSheet.Cells(5, 6).Value
'This code cycles through the different EVAL Table templates
ActiveSheet.Cells(1, 1).Value = CATS
ActiveSheet.Cells(2, 1).Value = DOGS
Dim k As Variant
For Each k In Tabs
controlThis = k & "-" & eval 'passes a string to the wdApp.contentcontrol
ActiveSheet.Rows.Hidden = False
ActiveSheet.Cells(1, 4).Value = k 'initialize k
ActiveSheet.Calculate
DoEvents
currentDifference = ActiveSheet.Cells(5, 6).Value 'stop blank tables from being produced using the total delta in the preprogrammed spreadsheet
If currentDifference = 0 Then 'since the total difference in the current analysis is 0 this bit of code skips to the next WonderPet
Else
controlThis = k & "-" & opener '(Was eval as variant used with thisTable array)passes a string to the wdApp.contentcontrol
Call PDFcrate 'Print the Table to a PDF file. Worked well and was made a subroutine.
Dim objWord As Object
Dim ws As Worksheet
'Dim cc As Word.Application.ContentControls
Set ws = ActiveWorkbook.Sheets("Sheet1")
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Open FileName:="myFilePath\Myfile.docx", noencodingdialog:=True ' change as needed
With objWord.ActiveDocument
.ContentControls(controlThis & " cats").Range.Text = eval.ActiveSheet.Cells(5, 4) 'These are the updates to the report for each content control with the title. Substituting SelectContentControlsByTitle() gives RTE-424 'Object Required'
.ContentControls(controlThis & " dogs").Range.Text = eval.ActiveSheet.Cells(5, 5)
.ContentControls(controlThis & " pets").Range.Text = eval.ActiveSheet.Cells(5, 6)
.ContentControls(controlThis & " Table).range. = 'Need to add the PDF to the report, perhaps using an RichTextConentConrols...additional suggestions welcomed (haven't researched it yet).
End With
Set objWord = Nothing
Word.Application.Documents.Close SaveChanges:=True 'Saves and Closes the document
Word.Application.Quit 'quits MS Word
End If
Next 'repeats for each tab with name "k" in the workbooks
Excel.Application.Workbooks(strXLname).Close
Next 'repeat for each evalTable
Excel.Application.Workbooks(CATS).Close
Excel.Application.Workbooks(DOGS).Close
End Sub
Word's content controls can't be picked up using a string as the index value the way other things can. The following line from the code sample in the question can't work:
.ContentControls(controlThis & " cats").Range.Text = eval.ActiveSheet.Cells(5, 4)
The only valid index value for a ContentControl is ID, which is a long number (GUID) assigned by the Word application when a ContentControl is generated.
The reason for this is that more than one content control can have the same Title (name) and/or Tag. Since this information is not unique it can't be used to pick up a single content control.
Instead, code needs to use either Document.SelectContentControlsByTitle or Document.SelectContentControlsByTag. These return an collection of content controls that meet the specified criterium. For example:
Dim cc as Word.ContentControls ' As Object if late-binding is used
With objWord.ActiveDocument
Set cc = .SelectContentControlsByTitle(controlThis & " cats")
'Now loop all the content controls in the collection to work with individual ones
End With
If it's certain there's only one content control with the Title, or only the first one is wanted, then it's possible to do this:
Dim cc as Word.ContentControl ' As Object if late-binding is used
With objWord.ActiveDocument
Set cc = .SelectContentControlsByTitle(controlThis & " cats").Item(1)
cc.Range.Text = eval.ActiveSheet.Cells(5, 4)
End With
Tip 1: Using ActiveDocument is not considered good practice for Word. As with ActiveCell (or anything else) in Excel, it's not certain that the "active" thing is the one that should be manipulated. More reliable is to use an object, which in this case can be assigned directly to the document being opened. Based on the code in the question:
Dim wdDoc as Object 'Word.Document
Set wdDoc = objWord.Documents.Open(FileName:="myFilePath\Myfile.docx", noencodingdialog:=True)
With wdDoc 'instead of objWord.ActiveDocument
Tip 2: Since the code in the question targets multiple content controls, rather than declaring multiple content control objects it might be more efficient to put the titles and values in an array and loop that.
This fixed it... looping through may have been the thing that got me unstuck.
The use of the plural ContentControls or singular ContentControl didn't seem to matter. My next trick is to get the tables into the word document... any thoughts?
Set wdDoc = Word.Application.Documents(wdDocReport)
Dim evalData(0 To 2) As Variant
evalData(0) = " CATS"
evalData(1) = " DOGS"
evalData(2) = " PETS"
Dim j As Variant
Dim i As Integer
i = 4
For Each j In evalData
Dim cc As Word.ContentControls
With Word.Application.Documents(wdDocReport)
.SelectContentControlsByTitle(controlThis & j).Item (1).Range.Text = ActiveWorkbook.ActiveSheet.Cells(5, i).Value
i = i + 1
End With
Next
Word.Application.Documents.Close SaveChanges:= True
Word.Application.Quit
Only one worksheet ever takes focus so the ActiveWorkbook and ActiveWorksheet didn't hurt me here

AutoFilter method of Range class failed in VB.NET

I am trying to use some Parsing i was able to tweak a little. If I use it in straight VBA in excel, it works fine. However, when I use the same code as a module in VB.NET I get the error in the title on the line of code
ws.Range(vTitles).AutoFilter()
(duh!) I am not sure what is going wrong in the conversion, since I am not a hardcore VB.Net programmer, so I am doing a lot of googling, but not finding much that works. Any ideas on how this could be fixed or do I have to abandon the idea of using this snippet in VB.Net?
Here is the code I am using:
'turned strict off or autofilter per http://www.pcreview.co.uk/threads/autofilter-method-of-range-class-failed.3994483/
Option Strict Off
Imports xl = Microsoft.Office.Interop.Excel
Module ParseItems
Public Sub ParseItems(ByRef fileName As String)
'Jerry Beaucaire (4/22/2010)
'Based on selected column, data is filtered to individual workbooks are named for the value plus today's date
Dim wb As xl.Workbook
Dim xlApp As xl.Application
Dim LR As Long, Itm As Long, MyCount As Long, vCol As Long
Dim ws As xl.Worksheet, MyArr As Object, vTitles As String, SvPath As String
'Set new application and make wb visible
xlApp = New xl.Application
xlApp.Visible = True
'open workbook
wb = xlApp.Workbooks.Open(fileName)
'Sheet with data in it
ws = wb.Sheets("Original Data")
'Path to save files into, remember the final "\"
SvPath = "G:\MC VBA test\"
'Range where titles are across top of data, as string, data MUST have titles in this row, edit to suit your titles locale
vTitles = "A1:L1"
'Choose column to evaluate from, column A = 1, B = 2, etc.
vCol = xlApp.InputBox("What column to split data by? " & vbLf & vbLf & "(A=1, B=2, C=3, etc)", "Which column?", 1, Type:=1)
If vCol = 0 Then Exit Sub
'Spot bottom row of data
LR = ws.Cells(ws.Rows.Count, vCol).End(xl.XlDirection.xlUp).Row
'Speed up macro execution
'Application.ScreenUpdating = False
'Get a temporary list of unique values from key column
ws.Columns(vCol).AdvancedFilter(Action:=xl.XlFilterAction.xlFilterCopy, CopyToRange:=ws.Range("EE1"), Unique:=True)
'Sort the temporary list
ws.Columns("EE:EE").Sort(Key1:=ws.Range("EE2"), Order1:=xl.XlSortOrder.xlAscending, Header:=xl.XlYesNoGuess.xlYes, _
OrderCustom:=1, MatchCase:=False, Orientation:=xl.Constants.xlTopToBottom, DataOption1:=xl.XlSortDataOption.xlSortNormal)
'Put list into an array for looping (values cannot be the result of formulas, must be constants)
MyArr = xlApp.WorksheetFunction.Transpose(ws.Range("EE2:EE" & ws.Rows.Count).SpecialCells(xl.XlCellType.xlCellTypeConstants))
'clear temporary worksheet list
ws.Range("EE:EE").Clear()
'Turn on the autofilter, one column only is all that is needed
ws.Range(vTitles).AutoFilter()
'Loop through list one value at a time
For Itm = 1 To UBound(MyArr)
ws.Range(vTitles).AutoFilter(Field:=vCol, Criteria1:=MyArr(Itm))
ws.Range("A1:A" & LR).EntireRow.Copy()
xlApp.Workbooks.Add()
ws.Range("A1").PasteSpecial(xl.XlPasteType.xlPasteAll)
ws.Cells.Columns.AutoFit()
MyCount = MyCount + ws.Range("A" & ws.Rows.Count).End(xl.XlDirection.xlUp).Row - 1
xlApp.ActiveWorkbook.SaveAs(SvPath & MyArr(Itm), xl.XlFileFormat.xlWorkbookNormal)
'ActiveWorkbook.SaveAs SvPath & MyArr(Itm) & Format(Date, " MM-DD-YY") & ".xlsx", 51 'use for Excel 2007+
xlApp.ActiveWorkbook.Close(False)
ws.Range(vTitles).AutoFilter(Field:=vCol)
Next Itm
'Cleanup
ws.AutoFilterMode = False
MsgBox("Rows with data: " & (LR - 1) & vbLf & "Rows copied to other sheets: " & MyCount & vbLf & "Hope they match!!")
xlApp.Application.ScreenUpdating = True
End Sub
End Module
Looks like you need to specify at least one optional parameter. Try this:
ws.Range(vTitles).AutoFilter(Field:=1)
I realize this was closed years ago, but I recently ran into this problem and wanted to add to the solution.
This seems to only work when specifically using the first optional Field parameter. I attempted this fix using the optional VisibleDropDown parameter and still got this error.
ws.Range["A1"].AutoFilter(VisibleDropDown: true); Gives error
ws.Range["A1"].AutoFilter(Field: 1); No error

formatting codes for footer not being applied and page orientation data mismatch

I have a worksheet(adHoc) where cell b28 contains
"&9 2014 YTD Financial Data for PP" & Chr(10) & " &D &T" & Chr(10) & " Version 1.0" & Chr(10) & " &F"
When I use the above to update the footer of another worksheet in a different workbook. I don't get the embedded formatting - it displays exactly what is contained in the cell b28.For example excel should see &9 and make the font 9 points.
I am also getting a datatype mismatch error with the page orientation. The contents of cell b36 is xlLandscape.
I posted a copy of this question last week on another board but did not get any answers. I hope someone here has answer.
http://www.mrexcel.com/forum/excel-questions/919033-updating-pagesetup-using-cells-master-worksheet-orientation-formatting-footer-excel-visual-basic-applications.html
This is the code I am using.
Sub page_setup()
Dim reportWB As Excel.Workbook
Dim sheet As Excel.Worksheet
'open report workbook - name of workbook is in cell b4
Set reportWB = Workbooks.Open(Workbooks("macros.xlsm").Sheets("adHoc").Range("b4").Value)
Dim leftFooter
leftFooter = Workbooks("macros.xlsm").Sheets("adHoc").Range("b28").Value
For Each sheet In reportWB.Sheets
With sheet
.PageSetup.leftFooter = leftFooter
.PageSetup.Orientation = Workbooks("macros.xlsm").Sheets("adHoc").Range("b36").Value
End With
Next
End Sub
Reading in your footer definitions like that they are treated as literal string, not code. You need to resolve the code to valid footer strings somehow.
For the LeftFooter string, you can use Evaluate to resolve it, but it will need to be written as if it's a Excel Formula, not VBA, so use
"&9 2014 YTD Financial Data for PP" & Char(10) & " &D &T" & Char(10) & " Version 1.0" & Char(10) & " &F"
Note the I use Char rather than Chr, the Excel formula equivalent.
For Orientation you are using a named constant, which won't work. Either put the value on your Excel sheet (2 in this case) or write your own code to resolve the name to its value
Working version (with corrected source data on sheet as descibed above)
Sub page_setup()
Dim reportWB As Excel.Workbook
Dim sheet As Excel.Worksheet
Dim wsSource As Worksheet
'open report workbook - name of workbook is in cell b4
Set wsSource = Workbooks("macros.xlsm").Sheets("adHoc")
Set reportWB = Workbooks.Open(wsSource.Range("b4").Value)
Dim leftFooter
leftFooter = wsSource.Range("b28").Value
For Each sheet In reportWB.Sheets
With sheet
.PageSetup.leftFooter = Evaluate(leftFooter)
.PageSetup.Orientation = wsSource.Range("b36").Value
End With
Next
End Sub
To handle the constants you could add a UDF that resolves the string names to values and call that from your settings sheet
Eg
Function GetConst(s As String) As Variant
Select Case s
Case "xlLandscape"
GetConst = xlLandscape
Case "xlPortrait"
GetConst = xlPortrait
' etc
End Select
End Function
Put in cell B36 GetConst("xlLandscape") (as a string, not formula), and change your Orientation line of code to
.PageSetup.Orientation = Evaluate(wsSource.Range("b36").Value)
Add any other named constants you want to the Select Case statement.
AFAIK, there is no (straightforward) way to do what you're trying to do. When you put code in a cell, and then call that cell's value in place of actual code, what VBA is trying to run is not:
.PageSetup.Orientation = xlLandscape
but rather:
.PageSetup.Orientation = "xlLandscape"
which will produce the errors and behavior you're seeing.
As rule of thumb, if your VBA code needs a string (ie, something in ""), or a number, you can do that calculation on the sheet and have the code pull in the value.
For everything else (there's Mastercard) put it in the code. For example:
leftfooter = cell1.value & Chr(10) & cell2.value & Chr(10) & cell3.value
(As a side note, I'm not familiar with the formatting it seems you're trying to do in that string... Those are generally set up through things like
With sheet.PageSetup.leftFooter.
.Font.Size = 9
'etc...
)

How to use a variable as one of the values in Excel VBA VLOOKUP

I'm using VBA in Excel and I'm assigning a VLOOKUP as a formula to a cell. It works fine, but I would like to use a variable that refers to the last cell that contains a value in the column.
In the example below, I would the value for $B$269 to change depending on the number of elements in the closed document.
"=VLOOKUP(B2,'Macintosh HD:Users:myself:Documents:[Master_Terms_Users.xlsm]Master_Terms_Users.csv'!$A$1:$B$269,2,FALSE)"
I know I want to use something along the lines of:
Range("B" & Rows.Count).End(xlUp).Address
With that said, I haven't been able to figure out how to incorporate the result, which is something like $B$269 into the VLOOKUP. I know that those formulas return the correct address because I've used it in Debug.Print.
I tried to do something like this:
"=VLOOKUP(B2,'Macintosh HD:Users:myself:Documents:[Master_Terms_Users.xlsm]Master_Terms_Users.csv'!$A$1:"&GetLastRowFunct&",2,FALSE)"
But that didn't work.
Here is my current code:
Sub GetLastRow()
Debug.Print GetLastRowFunct
End Sub
Function GetLastRowFunct() As String
Dim openNwb As Workbook
Const MasterPath = "Macintosh HD:Users:myself:Documents:"
Dim strNewFileName As String
strNewFileName = "Master_Terms_Users.xlsm"
Set openNwb = Workbooks.Open(MasterPath & strNewFileName)
Dim openNws As Worksheet
Set openNws = openNwb.Worksheets(1)
GetLastRowFunct = openNws.Range("B" & Rows.Count).End(xlUp).Address
openNwb.Close
End Function
Any recommendations would be appreciated.
I would rewrite that function to return the entire range address, including worksheet, workbook and path.
Function GetLastRowFunct() As String
Const MasterPath = "Macintosh HD:Users:myself:Documents:"
Dim openNwb As Workbook, strNewFileName As String
strNewFileName = "Master_Terms_Users.xlsm"
Set openNwb = Workbooks.Open(MasterPath & strNewFileName)
with openNwb.Worksheets(1)
GetLastRowFunct = .Range(.cells(1, 1), .cells(rows.count, "B").End(xlUp)).Address(1, 1, external:=true)
end with
openNwb.Close
End Function
The formula construction and assignment becomes simpler to deal with.
rng.formula = "=VLOOKUP(B2, " & GetLastRowFunct & ", 2, FALSE)"
tbh, I'm not sure if you have to supply your own square brackets or not on a Mac.

Excel VBA Runtime Error 1004 when renaming ActiveSheet

I'm at a loss when trying to figure out where this code is tripping up. I am looking to rename the activesheet by using a concat of two ranges on the activesheet and some static text. When only one worksheet is in the workbook, the code works great. As soon as a second worksheet is added, I get a Runtime Error 1004. I'll highlight the line of code where it is breaking. This code currently resides in a normal module.
Option Explicit
Sub updateName()
Dim fNumber
Dim pCheckNumber
Dim asName As String
Dim tempASName As String
Dim worksheetName As Object
If ActiveSheet.Name = "Launch Page" Then Exit Sub
fNumber = ActiveSheet.Range("FlightNumber").Value
pCheckNumber = ActiveSheet.Range("PerformanceCheckNumber").Value
If fNumber <> "" And pCheckNumber <> "" Then
tempASName = "Flight " & fNumber & " | Run " & pCheckNumber & " (0.0%)"
asName = tempASName
MsgBox ActiveSheet.Name & vbCr & asName
ActiveSheet.Name = asName
worksheetName.Caption = asName
Else
Exit Sub
End If
End Sub
I'm in the process of adding error checking to ensure that I don't have duplicate sheet names. However, due to the nature of the field names, this will never occur.
I appreciate all of the insights!
The error you are reporting is, most likely, provoked because of trying to rename a Worksheet by using a name already in use. Here you have a small code to avoid this kind of situations:
Dim newName As String: newName = "sheet1"
Dim addition As String: addition = "_2"
Do While (Not sheetNameFree(newName))
newName = newName & addition
Loop
Where sheetNameFree is defined by:
Function sheetNameFree(curName As String) As Boolean
sheetNameFree = True
For Each Sheet In ActiveWorkbook.Sheets
If (LCase(Sheet.Name) = LCase(curName)) Then
sheetNameFree = False
Exit Function
End If
Next Sheet
End Function
You can adapt this code to your specific needs (for example, by converting addition into a number which grows after each wrong name).
In your code I see one other problem (although it shouldn't be triggering a 1004 error): you are accessing the property Caption from an non-instantiated object (worksheetName), whose exact functionality is not too clear. Just delete this line.
NOTE: good point from KazJaw, you might be using an illegal character. If fNumber and pCheckNumber are numbers or letters, it would be OK.
NOTE2: if with worksheetName you want to refer to an ActiveX Label in your workSheet, better do: ActiveSheet.Label1.Caption (where Label1 is the name of the Label). You cannot define worksheetName as a Label, because it is not a "conventional Label".