I'm working on a POC to significantly reduce the lines of repetitive and lengthy Ampscript code for folks in my company that build our very complex emails which have tons of dynamic data, multi-language requirements, etc.

I'm on an engineering team trying to assist the folks that use Ampscript. I'm not an Ampscript developer. (And I'm hoping my skill level with Ampscript is the problem here, not that what I want to do is impossible.) :-)

Here's what I want to achieve with a POC:

  • Store rendered html of products owned by a customer in 1 to n columns in a data extension
  • Store a CONCAT function in another column in that same data extension that's written to concat all those 1 to n columns

The person building the email should be able to retrieve just the column with the pre-built CONCAT function in it and wrap it in TreatAsContent() which should result in a beautiful list of products in the email.

Here is the CONCAT string I'm storing in the HtmlController column of the DE concatenating just 2 columns for now

CONCAT(LOOKUP(%%=v(@productDE)=%%, 'Html1', 'CustomerID', %%=v(@customerId)=%%), LOOKUP(%%=v(@productDE)=%%, 'Html2', 'CustomerID', %%=v(@customerId)=%%))

Here is the POC email

    VAR @productOutput, @productDE
    /* this contains the customer id and the 1 to n html columns and the controller column */
    SET @productDE = 'customerproducts'
    SET @customerName = 'Faruzan'
    SET @customerId = '12345'

    SET @productOutput = Lookup(@productDE, 'HtmlController', 'CustomerID', @customerId)

  Greetings %%=V(@customerName)=%%
  These products are up for renewal  

The result I get replaces the variables as expected but it doesn't actually execute the CONCAT and LOOKUPs. So what's rendered is

CONCAT(LOOKUP(customerproducts, 'Html1', 'CustomerID', 12345), LOOKUP(customerproducts, 'Html2', 'CustomerID', 12345))

Please educate this poor C# dev who's been banging her head on her desk.

1 Answer 1


You would have to show that the field in the DE is actually AMPscript. TreatAsContent will just treat what content is in there as something to be processed, but it will not take the context of it being inside an AMPscript block in the call into account. It will instead run it based on the code in the TreatAsContent. Which is why your CustomerID and all are filling in, but not the overall code.

So if you were to change:

CONCAT(LOOKUP(%%=v(@productDE)=%%, 'Html1', 'CustomerID', %%=v(@customerId)=%%), LOOKUP(%%=v(@productDE)=%%, 'Html2', 'CustomerID', %%=v(@customerId)=%%))


%%=CONCAT(LOOKUP(%%=v(@productDE)=%%, 'Html1', 'CustomerID', %%=v(@customerId)=%%), LOOKUP(%%=v(@productDE)=%%, 'Html2', 'CustomerID', %%=v(@customerId)=%%))=%%

It should output right. (but see below as well around using Inline calls while inside block and how you should change that as well)

Another alternative is to Add a concat in the TreatAsContent to include open/close of AMPscript block

Something like:


Would also work.

But also, as a note, now that you are using CONCAT correctly to process, you should remove the inline V() calls. This is not the correct way to call these variables while inside an AMPscript block.

This is my recommended final content in the DE:

%%=CONCAT(LOOKUP(@productDE, 'Html1', 'CustomerID', @customerId), LOOKUP(@productDE, 'Html2', 'CustomerID', @customerId))=%%
  • Kind internet stranger, you are my absolute HERO! Assuming I adhere to the conventions you explained above, the 1 to n HTML columns which will contain a mix of HTML and Ampscript variables should render properly as well, yes?
    – Traveler
    Feb 15, 2023 at 20:26
  • For example, in one of the HTML columns I have <li>%%=v(@customerId)=%% $9.99</li> just to see if the @customerId gets replaced properly. I've tried the version you see there and also <li>%%=@customerId=%% $9.99</li> but neither render the actual customer ID.
    – Traveler
    Feb 15, 2023 at 20:34
  • I answered my follow up question. If the columns containing generated HTML also contain ampscript variable references, each individual LOOKUP must be wrapped in a TreatAsContent(). The next iteration of the CONCAT statement then looks like %%=CONCAT(TreatAsContent(LOOKUP(@productDE, 'Html1', 'CustomerID', @customerId)), TreatAsContent(LOOKUP(@productDE, 'Html2', 'CustomerID', @customerId)), TreatAsContent(LOOKUP(@productDE, 'Html3', 'CustomerID', @customerId)), TreatAsContent(LOOKUP(@productDE, 'Html4', 'CustomerID', @customerId)))=%%
    – Traveler
    Feb 15, 2023 at 21:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .