Salesforce, Python, SQL, & other ways to put your data where you need it

Need event music? 🎸

Live and recorded jazz, pop, and meditative music for your virtual conference / Zoom wedding / yoga class / private party with quality sound and a smooth technical experience

Edit Salesforce Metadata XML With Clicks, Not Code

22 Jul 2019 🔖 salesforce tutorials xml flow vscode
💬 EN

Table of Contents

Salesforce Administrators – sometimes, it’s faster or easier to change the structure of your Salesforce org by downloading files representing that structure to your local computer, editing them, and re-uploading them to Salesforce than it is to change the structure by clicking a lot of buttons in “Setup” in your web browser.

Think of it like using the “Data Loader,” but for your org’s structure instead of its data and with XML files instead of CSV files.

Perennially clever Nick provided a great example:

“I make some changes to profile and field XML files when I want to make a quick fix without clicking through the browser. IE update the field description.”

Read on to learn how to be more like Nick – always a solid idea!


The Bad Data

We’ll look at an org with a typo that got copy-pasted into 20 different fields across 2 different objects and fix the typo in one shot.


Software Installation & Configuration

This post will presume that you managed to install a lot of things pertaining to using Salesforce with software called VSCode on your computer.

The whole process is admin-friendly. It’s all “clicks, not code.”

However, there is a “first-time setup” process to follow.

Please visit my post Setting up VSCode to edit Salesforce metadata for thorough instructions on:


Download metadata files

Now that you’ve installed VSCode and connected it to your org, you need to download plain-text files called “metadata” that represent the current state of your Salesforce org onto your computer so that it’s easy to edit their contents.

Specify what files to request from Salesforce

  1. In VSCode, at left, under the navigation for the “project” you just created and gave a nice name, expand the folder called “manifest” and double-click “package.xml” to open it in the text editor area of VSCode at right.
  2. Take a look at the file. It’s full of text formatted in a pattern known as “XML.”
    • Do you know how to read XML? Check out my tutorial if not!
    • It’s probably about 30 lines long and contains text between “types” tags with code meaning things like, “Download all Apex classes to my hard drive from Salesforce,” “Download all Custom Settings to my hard drive from Salesforce,” etc.
  3. Edit the file. Carefully. Read my XML tutorial if you’re nervous. What you’re trying to do is leave only “<type>...</type>” tagsets in the XML you need.
    • Delete “<type>...</type>” tagsets you don’t care about (you don’t need to see the details of Apex Triggers if you don’t program them – it’s just going to make the download take longer).
    • Be sure not to accidentally delete the “<version>...</version>” tagset from your XML when deleting “<type>...</type>” tagsets you don’t need.
    • Add new “<type>...</type>” tagsets you do care about (learning exactly what to type is a bit of an art, but it’s usually pretty intuitive for most things if you start with an example), such as one for “CustomObject” if you’re trying to edit configuration files for objects.
    • Official documentation is here
    • A slightly overwhelming but official smorgasbord of example contents for a package.xml file is here
  4. Save your work. (“Ctrl+S” in Windows or File->Save)
  5. You can close the editor window for package.xml now.

For example, if you just want Account, Contact, and all custom objects, you can erase the entire contents of your package.xml file and replace it with this code (perhaps upgrading the version number if you’re reading this much later than I wrote the post):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Account</members>
        <members>Contact</members>
        <members>*</members>
        <name>CustomObject</name>
    </types>
    <version>46.0</version>
</Package>

That’s all that goes in package.xml! Not so bad, right?

(You can always re-edit it later if you want to fetch more or fewer files in subsequent requests to Salesforce.)

Notes:

  • Yes, even standard objects are considered CustomObject when specifying what you’d like to download via package.xml
  • Although custom objects can be downloaded with a simple “*” between “<members>...</members>” tagsets, using “*” will not download any standard objects. You have to specify standard objects one by one.
  • You don’t have to download all custom objects at once. You can also specify them one by one if you prefer.

Ask Salesforce for the files

This is known as “retrieving” code.

  1. Right-click on “package.xml” in the left-nav and click “SFDX: Retrieve Source in Manifest from Org
  2. When the little status box at lower right says you’re all done, close up “Manifest” at left and expand the folders “force-app,” then “main,” then “default,” then “objects” (presuming you meant to download objects).
  3. Do you see a lot of files? Yay!
    • (If not, dummy check: you asked to download some standard objects, or you actually have custom objects in your org, right?)

TO DO: Continue editing from here.


Edit and re-upload a configuration file

Edit a file on your computer

  1. Open one up in the VSCode file editor by double-clicking it. Make it one that’s still inactive and a first draft, and that you don’t care much about if you break it.
  2. Make some sort of relatively foolproof edit.
    • e.g. Copy & paste a “<variable>...</variable>” tagset and type a new value inside the “<name>...</name>” tagset embedded within.
    • Do you know how to read and write XML? Check out my tutorial if not!
  3. Save your work (File->Save or Ctrl+S).
  4. Close the editor tab for the file you just edited.

Here’re 4 screenshots of a flow I created with the web in Salesforce.

Screenshot number 1 out of 4 of my flow initial state in the Salesforce web editor

Screenshot number 2 out of 4 of my flow initial state in the Salesforce web editor

Screenshot number 3 out of 4 of my flow initial state in the Salesforce web editor

Screenshot number 4 out of 4 of my flow initial state in the Salesforce web editor

And here’s the XML I downloaded through VSCode that represents it:

<?xml version="1.0" encoding="UTF-8"?>
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
    <assignments>
        <name>Save_Name</name>
        <label>Save Name</label>
        <locationX>299</locationX>
        <locationY>50</locationY>
        <assignmentItems>
            <assignToReference>Variable_01</assignToReference>
            <operator>Assign</operator>
            <value>
                <elementReference>Name_Prompt</elementReference>
            </value>
        </assignmentItems>
        <connector>
            <targetReference>Greeting_Screen</targetReference>
        </connector>
    </assignments>
    <interviewLabel>Simple Hello World {!$Flow.CurrentDateTime}</interviewLabel>
    <label>Simple Hello World</label>
    <processMetadataValues>
        <name>BuilderType</name>
        <value>
            <stringValue>LightningFlowBuilder</stringValue>
        </value>
    </processMetadataValues>
    <processMetadataValues>
        <name>OriginBuilderType</name>
        <value>
            <stringValue>LightningFlowBuilder</stringValue>
        </value>
    </processMetadataValues>
    <processType>Flow</processType>
    <screens>
        <name>Greeting_Screen</name>
        <label>Greeting Screen</label>
        <locationX>411</locationX>
        <locationY>51</locationY>
        <allowBack>true</allowBack>
        <allowFinish>false</allowFinish>
        <allowPause>false</allowPause>
        <fields>
            <name>Greeting</name>
            <fieldText>Hello {!Variable_01}!</fieldText>
            <fieldType>DisplayText</fieldType>
        </fields>
        <showFooter>false</showFooter>
        <showHeader>true</showHeader>
    </screens>
    <screens>
        <name>Name_Prompt_Screen</name>
        <label>Name Prompt Screen</label>
        <locationX>186</locationX>
        <locationY>50</locationY>
        <allowBack>false</allowBack>
        <allowFinish>true</allowFinish>
        <allowPause>false</allowPause>
        <connector>
            <targetReference>Save_Name</targetReference>
        </connector>
        <fields>
            <name>Name_Prompt</name>
            <dataType>String</dataType>
            <fieldText>Name Prompt</fieldText>
            <fieldType>InputField</fieldType>
            <isRequired>true</isRequired>
        </fields>
        <showFooter>true</showFooter>
        <showHeader>true</showHeader>
    </screens>
    <startElementReference>Name_Prompt_Screen</startElementReference>
    <status>Draft</status>
    <variables>
        <name>Variable_01</name>
        <dataType>String</dataType>
        <isCollection>false</isCollection>
        <isInput>false</isInput>
        <isOutput>false</isOutput>
    </variables>
</Flow>

Screenshot of the XML behind my flow in VSCode

Wow! That’s a lot of code for very few boxes of Flow Designer, right? I suppose the difference between the visual and text representations of the same concept illustrate the reason that people often enjoy setting configurations with “clicks, not code.”

Nevertheless, the “copy-paste”-ability of the text file can’t be beat.

I’m just going to copy-paste Variable_01 to be a 2nd variable, Variable_02.

Screenshot of copying variable_01 XML

Screenshot of pasting variable_02 XML

Upload the file back to Salesforce

This is known as “deploying” code.

  1. Back in your navigation menu at left, right-click on the file you just edited and click “SFDX: Deploy Source to Org
    • Unfortunately, you can’t ctrl+click multiple files and deploy them all at once this way. Only one file will actually deploy, even though they all look selected on your screen.
    • Deploying an entire folder works by right-clicking it and deploying. (Note: possibly dangerous if others have been editing those other files through the web – you could overwrite their work.)
    • Similarly, you can right-click on package.xml to deploy all XML files mentioned therein from your computer to Salesforce. This has the same “you might be deploying old code” caveat.
  2. Once VSCode’s status pop-ups in the bottom right say you’re done…
  3. Open your Salesforce org, back out of your flow if you were editing it, re-open it, and see if the magic worked! Do you have a new variable in your resources?


Keep the files on your computer up-to-date over time

Now play with your flow in the web interface.

Save some changes.

To ensure you have a fresh copy on your computer before editing the XML representing your flow:

  1. Open VSCode
  2. Right-click on the file (or on the package.xml for everything) and do a “Retrieve” instead of a “Deploy.”

Warning

Caution: Don’t click the adjacent “deploy” option!

Unfortunately, “Retrieve” & “Deploy” are right next to each other.

  • Q: Why wouldn’t it be safe to deploy?
  • A: As you’re aware if you’re trying to “retrieve” code fresh from Salesforce, the copies of code on your computer are out-of-date.
    • Accidentally clicking “Deploy” instead of “Retrieve” could overwrite hard work you’ve done through your web browser with no easy way to recover.

If I use VSCode re-open the XML file containing a representation of my flow, after re-downloading the latest version of it, I can see that it’s longer than it used to be..

Change 1: Within the <assignmentItems>...</assignmentItems> tagset representing the assignment called “Save Name,” an entirely new <assignmentItems>...</assignmentItems> tagset has been added to the code setting the value of Variable_02, just like I did with clicks.

        <assignmentItems>
            <assignToReference>Variable_02</assignToReference>
            <operator>Assign</operator>
            <value>
                <stringValue>XYZZY-{!Name_Prompt}-XYZZY</stringValue>
            </value>
        </assignmentItems>

Change 2: The <screens>...</screens> tagset representing the screen called “Greeting Screen” has been updated so that its “Greeting” display-text field says “Hello {!Variable_01} {!Variable_02}!” instead of “Hello {!Variable_01}!

<fieldText>Hello {!Variable_01} {!Variable_02}!</fieldText>

Hooray – I successfully updated my computer’s copy of the XML code to keep it in sync with what’s going on in my Salesforce org through web-based edits.


Your Turn

  • If you’re an administrator, I hope you can make yourself more productive with a bit of “code, not clicks”

https://salesforce.stackexchange.com/questions/159005/listing-of-all-standard-profiles-and-their-metadata-api-names

Thanks for making it all the way through!

--- ---