¿Necesitas saber qué campos tiene una Data Extension, su tipo, longitud, y si son llaves primarias?
Este script en una CloudPage te permite ingresar el nombre de una DE o el ID de una carpeta y obtener toda esa información, incluyendo el número de filas que contiene cada una.
Ideal para auditar tu Business Unit o documentar tus estructuras de datos en Salesforce Marketing Cloud (SFMC).
🧪 ¿Qué hace este script?
- Te permite seleccionar si quieres buscar por nombre de Data Extension o por carpeta (CategoryID).
- Recupera todas las DEs asociadas.
- Extrae los metadatos de cada campo: nombre, tipo, longitud, si es llave primaria y si acepta valores nulos.
- También recupera el número de filas de cada DE.
- Muestra todo en una tabla HTML descargable como CSV.
🧩 Código completo (AMPscript + SSJS + HTML)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Extraer metadatos de campos de DE</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
h1 { color: #003366; }
form { margin-bottom: 30px; padding: 20px; border: 1px solid #ccc; width: 400px; }
label, input, select, button { display: block; margin-top: 10px; width: 100%; }
table { border-collapse: collapse; width: 100%; margin-top: 30px; }
th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.download-button { margin-top: 20px; }
</style>
</head>
<body>
<h1>Extraer metadatos de campos de DE</h1>
<form method="GET">
<label><strong>Destino:</strong></label>
<label><input type="radio" name="target" value="de" %%[IF RequestParameter("target") == "de" THEN]%%checked%%[ENDIF]%%> Data Extension (nombre de la DE)</label>
<label><input type="radio" name="target" value="folder" %%[IF RequestParameter("target") == "folder" OR EMPTY(RequestParameter("target")) THEN]%%checked%%[ENDIF]%%> Carpeta (Category ID)</label>
<label for="identifier"><strong>Identificador:</strong></label>
<input type="text" name="identifier" id="identifier" value="%%=v(RequestParameter("identifier"))=%%" required>
<button type="submit">Procesar</button>
</form>
<script runat="server">
Platform.Load("Core", "1.1");
var target = Request.GetQueryStringParameter("target") || "folder";
var identifier = Request.GetQueryStringParameter("identifier");
if (identifier) {
var des = [];
// Buscar por carpeta o por nombre de DE
if (target === "folder") {
des = DataExtension.Retrieve({
Property: "CategoryID",
SimpleOperator: "equals",
Value: parseInt(identifier)
});
} else {
des = DataExtension.Retrieve({
Property: "Name",
SimpleOperator: "equals",
Value: identifier
});
}
if (des && des.length > 0) {
Write('<button class="download-button" onclick="downloadTableAsCSV()">Descargar CSV</button>');
Write("<table id='deTable'><tr><th>Nombre DE</th><th>Customer Key</th><th>Campo</th><th>Tipo</th><th>Longitud</th><th>Llave Primaria</th><th>Nullable</th><th># Filas</th></tr>");
for (var i = 0; i < des.length; i++) {
var de = des[i];
var deName = de.Name;
var deKey = de.CustomerKey;
Platform.Variable.SetValue("@deName", deName);
</script>
%%[
SET @rowCount = DataExtensionRowCount(@deName)
]%%
<script runat="server">
var rowCount = Variable.GetValue("@rowCount");
if (!rowCount || rowCount === "") {
rowCount = "No disponible";
}
try {
var myDE = DataExtension.Init(deKey);
var fields = myDE.Fields.Retrieve();
if (fields && fields.length > 0) {
for (var j = 0; j < fields.length; j++) {
var f = fields[j];
Write("<tr>" +
"<td>" + deName + "</td>" +
"<td>" + deKey + "</td>" +
"<td>" + f.Name + "</td>" +
"<td>" + f.FieldType + "</td>" +
"<td>" + (f.MaxLength || "") + "</td>" +
"<td>" + (f.IsPrimaryKey === true ? "Sí" : "") + "</td>" +
"<td>" + (f.IsNullable === true ? "Sí" : "No") + "</td>" +
"<td>" + rowCount + "</td>" +
"</tr>");
}
} else {
Write("<tr><td colspan='8'><em>No se encontraron campos para la DE: " + deName + "</em></td></tr>");
}
} catch (e) {
Write("<tr><td colspan='8' style='color:red;'>Error al obtener campos para la DE: " + deName + " - " + String(e) + "</td></tr>");
}
}
Write("</table>");
} else {
Write("<p style='color:red;'>No se encontraron Data Extensions para el identificador proporcionado.</p>");
}
}
</script>
<script>
function downloadTableAsCSV() {
var table = document.getElementById("deTable");
var rows = table.querySelectorAll("tr");
let csvContent = "";
rows.forEach(row => {
let cols = row.querySelectorAll("td, th");
let line = Array.from(cols).map(col => '"' + col.innerText.replace(/"/g, '""') + '"').join(",");
csvContent += line + "\n";
});
var blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
var link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "de_metadata_export.csv";
link.click();
}
</script>
</body>
</html>
recuerda que este y otros snippets de sfmc están disponibles en el repo de nuestra comunidad: https://github.com/jcgalindof/salesforce-cancun
✅ Recomendaciones
- Puedes guardar esta CloudPage como recurso privado en tu entorno de desarrollo de SFMC.
- Asegúrate de tener los permisos adecuados para usar DataExtension.Retrieve() y Init() en la BU.
- Úsalo para auditorías técnicas, limpieza de datos o documentación de estructuras complejas.
- Funciona mejor con carpetas pequeñas (menos de 100 DEs) para evitar timeouts de script.