% ==========================================================
% vule.m
% Visualizador y filtro de datos para [Link]
% Muestra una tabla con encabezados del 5-ene al 31-ene,
% permite filtrar, exportar los datos filtrados y visualizar
% una gráfica de superficie 3D.
% ==========================================================
clc; clear; close all;
% ==== 1) Buscar automáticamente el archivo ====
userPath = getenv('USERPROFILE');
downloadPath = fullfile(userPath, 'Downloads', '[Link]');
if isfile(downloadPath)
filename = downloadPath;
fprintf('Archivo encontrado en: %s\n', filename);
else
[file, path] = uigetfile({'*.xlsx;*.xls','Archivos Excel
(*.xlsx, *.xls)'}, 'Selecciona el archivo [Link]');
if isequal(file,0)
error('No se seleccionó ningún archivo.');
end
filename = fullfile(path, file);
end
% ==== 2) Leer datos ====
try
raw = readmatrix(filename, 'Sheet', 'Hoja4');
fprintf('Archivo cargado correctamente (%d filas, %d
columnas)\n', size(raw,1), size(raw,2));
catch ME
error('Error al leer el archivo Excel: %s', [Link]);
end
% Eliminar filas completamente vacías
raw = raw(~all(isnan(raw),2), :);
[nRows, nCols] = size(raw);
% ==== 3) Encabezados personalizados ====
columnNamesFull = { ...
'5-ene','6-ene','7-ene','8-ene','9-ene','10-ene','11-
ene','12-ene','13-ene','14-ene', ...
'15-ene','16-ene','17-ene','18-ene','19-ene','20-ene','21-
ene','22-ene','23-ene','24-ene', ...
'25-ene','26-ene','27-ene','28-ene','29-ene','30-ene','31-
ene'};
if numel(columnNamesFull) > nCols
columnNames = columnNamesFull(1:nCols);
elseif numel(columnNamesFull) < nCols
columnNames = columnNamesFull;
for k = (numel(columnNamesFull)+1):nCols
columnNames{end+1} = sprintf('Columna_%d', k);
end
else
columnNames = columnNamesFull;
end
% ==== 4) Convertir a tabla ====
validVarNames = [Link](columnNames);
dataTable = array2table(raw, 'VariableNames', validVarNames);
% ==== 5) Crear interfaz ====
fig = uifigure('Name','Visualizador ROSA', 'Position',[200 150 1100
650]);
uilabel(fig, 'Text','Filtro (buscar en toda la tabla):', ...
'Position',[20 600 220 22], 'FontWeight','bold');
filterField = uieditfield(fig,'text', 'Position',[250 600 420 24]);
btnClear = uibutton(fig, 'push', 'Text','Limpiar', 'Position',[680
600 80 24]);
btnExport = uibutton(fig, 'push', 'Text','Exportar filtrado',
'Position',[780 600 140 24]);
btnPlot3D = uibutton(fig, 'push', 'Text','Gráfica 3D', 'Position',
[930 600 130 24]);
t = uitable(fig, 'Data', dataTable, ...
'Position',[20 80 1060 500], ...
'ColumnSortable', true, ...
'ColumnWidth','auto');
[Link] = columnNames;
statusLabel = uilabel(fig, 'Text', ...
sprintf('Registros mostrados: %d / %d', height(dataTable),
height(dataTable)), ...
'Position',[20 40 400 22]);
fprintf('Interfaz lista. Use el campo "Filtro" para buscar,
"Exportar" para guardar o "Gráfica 3D" para visualizar.\n');
% ==== 6) Conectar callbacks ====
[Link] = @(src,event) applyFilter(src, t,
dataTable, statusLabel);
[Link] = @(src,event) clearFilter(filterField, t,
dataTable, statusLabel);
[Link] = @(src,event) exportFiltered(t);
[Link] = @(src,event) plot3DSurface(t,
columnNames, raw);
% ==== 7) Funciones auxiliares (fuera del alcance principal) ====
function applyFilter(src, t, dataTable, statusLabel)
txt = lower(strtrim(string([Link])));
if txt == ""
[Link] = dataTable;
else
C = table2cell(dataTable);
S = lower(string(C));
mask = any(contains(S, txt), 2);
if any(mask)
[Link] = dataTable(mask, :);
else
[Link] = dataTable(1:0, :);
end
end
[Link] = sprintf('Registros mostrados: %d / %d',
height([Link]), height(dataTable));
end
function clearFilter(filterField, t, dataTable, statusLabel)
[Link] = "";
[Link] = dataTable;
[Link] = sprintf('Registros mostrados: %d / %d',
height(dataTable), height(dataTable));
end
function exportFiltered(t)
currentT = [Link];
if isempty(currentT)
uialert([Link], 'No hay datos para exportar.',
'Exportar');
return;
end
outFolder = fullfile(getenv('USERPROFILE'),'Downloads');
outName = fullfile(outFolder, 'ROSA_filtrado.xlsx');
try
writetable(currentT, outName, 'Sheet','Filtrado');
uialert([Link], sprintf('Archivo exportado:\n%s',
outName), 'Exportación completada');
catch ME
uialert([Link], sprintf('Error al exportar: %s',
[Link]), 'Error');
end
end
function plot3DSurface(t, ~, ~)
% Obtener datos actuales de la tabla (pueden estar filtrados)
currentData = [Link];
if isempty(currentData)
uialert([Link], 'No hay datos para graficar.',
'Gráfica 3D');
return;
end
% Convertir tabla a matriz numérica
Z = table2array(currentData);
% Crear matrices de coordenadas X e Y
[X, Y] = meshgrid(1:size(Z,2), 1:size(Z,1));
% Crear nueva figura para la gráfica 3D
fig3D = figure('Name', 'Gráfica de Superficie 3D',
'NumberTitle', 'off');
% Crear gráfica de superficie
surf(X, Y, Z, 'FaceColor', 'interp', 'EdgeColor', 'none');
% Personalizar la gráfica
xlabel('Días (columnas)', 'FontSize', 11);
ylabel('Registros (filas)', 'FontSize', 11);
zlabel('Valores', 'FontSize', 11);
title('Visualización de Superficie 3D - Datos ROSA',
'FontSize', 12, 'FontWeight', 'bold');
% Agregar colormap y barra de colores
colormap('jet');
colorbar;
% Mejorar la visualización
grid on;
view(45, 30);
camlight('headlight');
material dull;
fprintf('Gráfica 3D creada exitosamente (%d filas x %d
columnas).\n', size(Z,1), size(Z,2));
end