Skip to content
This repository has been archived by the owner on Jan 19, 2021. It is now read-only.

Provisioning error when re-applying list calculated fields: The formula refers to a column that does not exist. #2081

Open
chaoshades opened this issue Feb 20, 2019 · 3 comments

Comments

@chaoshades
Copy link

Which PnP repository should you use to report the issue?

PnP Sites Core - https://github.com/OfficeDev/PnP-Sites-Core
Version: 3.6.1902.2

I'm using the PowerShell cmdlets. I installed it with :
Install-Module SharePointPnPPowerShellOnline

Category

[x] Bug
[ ] Enhancement

Environment

[x] Office 365 / SharePoint Online
[ ] SharePoint 2016
[ ] SharePoint 2013

Expected or Desired Behavior

I have manually created a site collection with SharepointOnline and exported a template from it with the Powershell cmdlet. I am trying to apply this template to a blank site collection. I have a calculated field on one of my lists, which, for simplicity, have been reduced to only copy the value from another column.
Formula looks like this in the template: =[{fieldtitle:EndDate}]
And the names in the definition of the field are:
<Field Type="DateTime" DisplayName="End" [...] StaticName="EndDate" Name="EndDate" [...] />
I expected the list to be updated on the blank site, like the other ones with no calculated fields.

Note : I know (from issue #633) about the fields order and so far, my calculated fields are always after the fields they refers to.

Observed Behavior

Creating the list the first time, all was good.
When I re-applied the template, without changing anything (just to test if I could update my list by re-provisioning), I received the error : "The formula refers to a column that does not exist. Check the formula for spelling mistakes or change the non-existing column to an existing column." After some research in the issue tracker, I have found this resolved issue #849. So, I then tried by removing {fieldtitle} and replacing the name with the DisplayName which give this formula instead : =[End] and it worked.
I deleted the list, re-applied the template and it worked on the initial creation too.

Steps to Reproduce

  • Create a list with a calculated field in it that refers another a column within the list
    • Generate a template using PnP provisioning framework
    • Apply template on a newly created site collection
    • Apply again the same template on the same created site collection
@dstretch
Copy link

I have exactly the same problem reapplying a template and the solution above worked for me too.

Change formula references from [{fieldtitle:InternalName}] to [Display Name].

Thanks

@nilang-shah
Copy link

@chaoshades recommendation also solved my problem!

@bhlaws
Copy link

bhlaws commented Jan 7, 2021

I just hit the same issue. I agree: the solution is to replace the reference to the internal name with the field's Display Name. To assist in this, I created the following PowerShell script. I run this after the Get-PnPProvisioningTemplate.

Sorry - I know it's not the most efficient code and doesn't cover all edge cases or potential errors, but it did the trick for me. :-) Hopefully this will help someone else, too.

# We're using a for loop instead of a foreach so that we can have an index that we can use to update the original $template object
for($i = 0; $i -lt $template.Lists.Count; $i++)
{
    $list = $template.Lists[$i]

    # Find all calculated fields. Because of a PnP bug, a template uses [{fieldtitle:<internalFieldName>}] in calculated field formulas and not the field's Display Name
    # The code below finds all instances of {fieldtitle:xxxx} in the field's formula, figures out all of the internal names used (the xxxx after the "fieldtitle:"),
    # looks up the field's Display Name, and replaces {fieldtitle:xxxx} in the calculation with the field's Display Name.
    for($j = 0; $j -lt $list.Fields.Count; $j++)
    {
        if($List.Fields[$j].SchemaXml -like '*Type="Calculated"*')
        {
            $fields = @()
            $xml = [xml]$list.Fields[$j].SchemaXml
        
            # Find all the field references
            $chunksWithFieldTitles = $xml.Field.Formula -split "{fieldtitle:" -like "*}]*"

            # Get all of the internal field names being used
            foreach($chunk in $chunksWithFieldTitles)
            {
                $fields += $chunk.Split("}") | Select-Object -First 1
            }

            # Look up the Display Name based on the internal field name, then update the formula
            foreach($field in $fields | Select-Object -Unique)
            {
                $lookupField = [xml]($list.Fields | Where-Object {$_.SchemaXml -like "*Name=""$($field)""*"}).SchemaXml
                $displayName = $lookupField.Field.DisplayName
                $template.Lists[$i].Fields[$j].SchemaXml = $template.Lists[$i].Fields[$j].SchemaXml.Replace("{fieldtitle:$($field)}", $displayName)
            }
        }
    }
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants