Partager via


Utilizando DateTimePicker en Excel con VSTO

Estoy trabajando en un proyecto personal (hasta que deje de serlo y se convierta en una tool que quiero usar en el trabajo) sobre Excel. No hay mucho que explicar sobre el DateTimePicker, la idea es poder seleccionar fechas, sin tener que escribirlas a mano:

image

Luego de ver unos minutos sobre las opciones de Data Validation, opté por crear una proyecto con VSTO. Data Validation permitiría verificar que se esté ingresando una fecha valida, pero el mensaje de error que despliega no es la más amigable del mundo.

Les comparto aquí el código que escribí asociado al sheet. Entiendo que lo mismo puede lograrse mediante VBA, pero me siento más cómodo con C#:

 

        void Table_SelectionChange(Excel.Range Target)
        {
          AddPickerIfDateTimeCellSelected(Target);
        }
  
        private void AddPickerIfDateTimeCellSelected(Excel.Range Target)
        {
            var isSingleCell = Target.Columns.Count == 1 && Target.Columns.Count == 1;
            var isDateColumn = Target.Column == _startDateColumnIndex || Target.Column == _dueDateColumnIndex;
            if (isSingleCell && isDateColumn)
            {
                _dateTimeCellIsSelected = true;
                this.CreateDateTimePicker(Target);
            }
            else if (_dateTimeCellIsSelected)
            {
                _dateTimePicker.Delete();
                _dateTimeCellIsSelected = false;
            }
        } 
  
        private void CreateDateTimePicker(Microsoft.Office.Interop.Excel.Range Target)
        {
            if (_dateTimePicker != null)
            {
                _dateTimePicker.Delete();
            }
            _dateTimePicker = this.Controls.AddDateTimePicker(Target, "dateTimePicker");
            _dateTimePicker.Format = DateTimePickerFormat.Short; 
  
            _dateTimePicker.Value = Convert.ToDateTime(Target.get_Value(System.Reflection.Missing.Value));
            _dateTimePicker.ValueChanged += (s, e) => Target.set_Value(System.Reflection.Missing.Value, _dateTimePicker.Value);
        }
  

El código verifica que el rango de la selección corresponda a una única celda, y que pertenezca a algunas de las dos columnas definidas para fecha. Luego crea o elimina un DateTimePicker ante la selección o deselección de la celda. Tal vez no es el código más prolijo que alguien pueda escribir, pero after all estamos hablando de COM intefaces y funciona :).

Saludos!