miércoles, 22 de abril de 2015

Envío email a traves de librerias outlook


Con esta función se consigue enviar un correo utilizando las librerias de outlook. existen varias opciones tanto de formato como de tipo de envio ya sea enviado directamente o levantando el cliente Outlook para comprobar antes de enviar. Para ello primero vamos a crear dos variables locales tipo automation asignando librerias de Outlook.

    - OMail Automation 'Microsoft Outlook 9.0 Object ibrary'.MailItem
    - OApp Automation 'Microsoft Outlook 9.0 Object ibrary'.Application



En este caso se ha puesto la versión 9.0 porque es la versión que tengo instalada en mi equipo. Es necesario que todos los equipos desde donde se va lanzar esta función tengan instalada mínimo la misma versión con la que se han definido las variables. No habría problema con los equipos que tengan instalada una versión superior de las librerías ya que leerían las dll perfectamente no asi los equipos con versiones anteriores.


la funcion creada tiene varios parámetros :
eMail - dirección de correo del o de los destinatarios.
RutaPlantilla - Es la ruta al fichero de plantilla con la que abrir el correo.
RutaYFichero - Ruta del documento adjunto.
MostrarCorreo - Es un booleano para determinar si queremos o no levantar el cliente Outlook antes de enviar el correo

IF ISCLEAR(OApp) THEN
  CREATE(OApp,FALSE,TRUE);
//OMail := OApp.CreateItem(0); //Si NO utilizamos plantillas
OMail := OApp.CreateItemFromTemplate(rutaplantilla); //Si se usan plantillas
OMail."To":=eMail;
IF RutayFichero <> '' THEN
  OMail.Attachments.Add(RutayFichero); //Si queremos adjuntar un fichero
OMail.Subject :=Asunto;
//OMail.Body := ‘El cuerpo del mensaje’; //O ponemos este código o el de la plantilla.
//OMail.OriginatorDeliveryReportRequested := TRUE; //Confirmación de recepción.
//OMail.ReadReceiptRequested := TRUE; //Confirmación de lectura.
IF MostrarCorreo=TRUE THEN
  OMail.Display //levanta el cliente correo si no se llama a esta funcion envai el correo                 directamente.
ELSE
OMail.Send;



jueves, 5 de marzo de 2015

Crear Trigger en SQL para insertar un registro en el que algunos campos son de tipo "no null"

Tenemos un proceso para alimentar una tabla de navision directamente desde sql. El proceso unicamente alimenta dos campos que son el campo1 y el campo4 y quieren que se calculen el campo2 y campo3 qeu corresponden a la fecha y hora. la tabla también tiene los 4 campos definidos como no Null por lo que necesitamos que esos campos se cumplimente al insertar sin dar error ya que como hemos mencionado antes dos de los campos los tenemos que calcular, la cuestión es ¿cuando?.

Lo que hemos hecho ha sido utilizar el desencadenante INSTEAD OF INSERT, el desencadenador INSTEAD OF INSERT de una vista o tabla genera una instrucción INSERT en la tabla base mediante los datos de la tabla inserted asi tenemos acceso a los campos del registro que se está insertando, al realizar el insert sobre la tabla real dentro del trigger disponemos (consulta select de la tabla inserte) el valor de los campos insertados los dos que no venian informados los hemos calculado.

Para calcular el time lo que ponemos es la parte de fecha como a 0 pero en sql no puede haber fecha 0 y lo que hacemos es coger la primera fecha disponible "1754-01-01" y cumplimentamos la parte de la hora.  
"CAST('1754-01-01 '+CONVERT(CHAR(8), GETDATE(), 108) AS DATETIME)"

Para calcular la fecha lo que hacemos es poner la fecha de hoy y completamos a 0 la hora.
"CONVERT(CHAR(10),GETDATE(), 120)"

Definición de la tabla TablaEjemplo
Campo1 nvarchar(2)
Campo2 Fecha datetime
Campo3 Time datetime
Campo4 int

ALTER TRIGGER [dbo].[ActualizarFechas]
ON [dbo].[TablaEjemplo]
       INSTEAD OF INSERT
          AS BEGIN
            declare @cpo1 nvarchar(2); declare @cpo2 int;

            SELECT @cpo1= CampoTabla1,@cpo2=CampoTabla4
            FROM inserted
            INSERT INTO [dbo].[TablaEjemplo] ([Maquina],[Fecha],[Hora],[Contador])
            VALUES (@cpo1,
                            CONVERT(CHAR(10),GETDATE(), 120),
                            CAST('1754-01-01 '+CONVERT(CHAR(8), GETDATE(), 108) AS DATETIME),
                           @cpo2)
END

miércoles, 25 de febrero de 2015

Identificar entorno NAV versiones RTC

Exite la posibilidad en RTC de identificar la base de datos en la que nos encontramos, esto permite que en un vistazo veamos la base de datos en la que estamos trabajando ya sea en pruebas o en real en vez de tener que ir a buscar esta información cada vez que queramos comprobar donde estamos. para configurarlo es necesario ir a Información de empresa --> Indicador del sistema
En el indicador del sistema se establece el tipo de indicador, si queremos poner un texto nuestro utilzamos la opción de "texto personalizado". En el campo de enfasis se definen los matices con los que queremos que se refleje el indicador. En texto personalizado definimos el texto del indicador.

Error al exportar objetos "El archivo de objetos no se puede utilizar con esta versión del programa"

En ocasiones al realizar la exportación de un fob a una carpeta surge este error:
La solución más fácil que hemos encontrado es crear una carpeta nueva para que se pueda exportar el fichero o bien borrar los fobs de la versión superior que estén en esa ruta. Lo que hace Navision es realizar una comprobación para ver si un fichero que se ha generado en versiones de la base de datos superiores se ha exportado en esa misma ruta y al ver que si se ha realizado da el error.

viernes, 4 de noviembre de 2011

Comprobar numeración de tarjeta de crédito

Al igual que con los números de cuenta cada tipo de tarjeta de crédito tiene una configuración determinada, os voy a dejar un bloque de código donde se comprueban los formatos para los diferentes tipos de tarjetas de credito, Visa, MasteCard, American Express, Discover y Dinners Club. A ver si os vale


  vDigito:=COPYSTR(NumeroTarjeta,1,1);
  vDigito2:=COPYSTR(NumeroTarjeta,1,2);
  vDigito4:=COPYSTR(NumeroTarjeta,1,4);

//American express
  IF "Tipo Tarjeta"="Tipo Tarjeta"::"American Express" THEN BEGIN
    IF (vDigito2 = '34') OR (vDigito2 = '37') THEN BEGIN
      IF (STRLEN(NumeroTarjeta) <> 15) THEN
        ERROR(TXT1,STRLEN(NumeroTarjeta),"Tipo Tarjeta");
    END
    ELSE
      ERROR(TXT2,rPolizas.NumeroTarjeta,rPolizas."Tipo Tarjeta");
  END;

//Visa
  IF "Tipo Tarjeta"="Tipo Tarjeta"::Visa THEN BEGIN
    IF vDigito = '4' THEN BEGIN
      IF (STRLEN(NumeroTarjeta) <> 13) AND (STRLEN(NumeroTarjeta) <> 16) THEN
        ERROR(TXT1,STRLEN(NumeroTarjeta),"Tipo Tarjeta");
    END
    ELSE
      ERROR(TXT2,NumeroTarjeta,"Tipo Tarjeta");
  END;

//MasterCard
  IF "Tipo Tarjeta"="Tipo Tarjeta"::MasterCard THEN BEGIN
    IF (vDigito2 >= '51') AND (vDigito2 <= '55') THEN BEGIN
      IF (STRLEN(NumeroTarjeta) <> 16) THEN
        ERROR(TXT1,STRLEN(NumeroTarjeta),"Tipo Tarjeta");
    END
    ELSE
         ERROR(TXT2,NumeroTarjeta,"Tipo Tarjeta");
  END;

//Discover
  IF "Tipo Tarjeta"=."Tipo Tarjeta"::Discover THEN BEGIN
    IF vDigito4 = '6011' THEN BEGIN
      IF (STRLEN(NumeroTarjeta) <> 16) THEN
        ERROR(TXT1,STRLEN(NumeroTarjeta),"Tipo Tarjeta");
    END
    ELSE
      ERROR(TXT2,NumeroTarjeta,"Tipo Tarjeta");
  END;  

//Diners club
  IF "Tipo Tarjeta"="Tipo Tarjeta"::"Diners club" THEN BEGIN
    IF (vDigito2 = '30') OR (vDigito2 = '36') OR (vDigito2 = '38') THEN BEGIN
      IF (STRLEN(NumeroTarjeta) <> 14) THEN
        ERROR(TXT1,STRLEN(NumeroTarjeta),"Tipo Tarjeta");
    END
    ELSE
      ERROR(TXT2,NumeroTarjeta,"Tipo Tarjeta");
  END;

//Comprobar numeración de tarjeta
  vNuevoNT:='';
  FOR vIndex:=1 TO STRLEN(NumeroTarjeta) DO BEGIN
     vNuevoNT:='';
     IF vIndex MOD 2 <> 0 THEN BEGIN
        EVALUATE(vNoperar,FORMAT(NumeroTarjeta[vIndex]));
        IF vNoperar * 2 > 9 THEN BEGIN
          vNuevoNT:=FORMAT((vNoperar*2)-9);
        END
        ELSE BEGIN
            vNuevoNT:=FORMAT((vNoperar*2));
        END    
     END
     ELSE BEGIN
         vNuevoNT:=FORMAT(NumeroTarjeta[vIndex]);
     END;
     EVALUATE(vConvert,vNuevoNT);
     vResultado+=vConvert;
  END;
  IF (vResultado MOD 10 <> 0) AND (vResultado > 150) THEN
    ERROR('El numero de tarjeta %1 no es correcto',NumeroTarjeta);
END;

Sacar el dígito control de numero cuenta para comprobar si es correcto

Voy a dejar un bloque de código donde se realiza la comprobación del dígito de control de un número de cuenta para saber si este es correcto.



//Comprobar longitud y numero de cuenta
Suma1Int:=0;
Suma2Int:=0;
IF vTXTNumCuenta <> '' THEN BEGIN
  FOR vIndex:=1 TO 10 DO BEGIN
     Suma1:=0;
     Suma2:=0;
     EVALUATE(Digit1,COPYSTR(vTXTNumCuenta,9,1));
     EVALUATE(Digit2,COPYSTR(vTXTNumCuenta,10,1));
     CASE vIndex  OF
       1: BEGIN
            EVALUATE(Suma1,COPYSTR(vTXTNumCuenta,1,1));
            EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,11,1));
            Suma1Int:=Suma1*4;
            Suma2Int:=Suma2*1;
          END;

       2: BEGIN
            EVALUATE(Suma1,COPYSTR(vTXTNumCuenta,2,1));
            EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,12,1));
            Suma1Int+=Suma1*8;
            Suma2Int+=Suma2*2;
          END;

       3: BEGIN
            EVALUATE(Suma1,COPYSTR(vTXTNumCuenta,3,1));
            EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,13,1));
            Suma1Int+=Suma1*5;
            Suma2Int+=Suma2*4;
          END;

       4: BEGIN
            EVALUATE(Suma1,COPYSTR(vTXTNumCuenta,4,1));
            EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,14,1));
            Suma1Int+=Suma1*10;
            Suma2Int+=Suma2*8;
          END;

       5: BEGIN
            EVALUATE(Suma1,COPYSTR(vTXTNumCuenta,5,1));
            EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,15,1));
            Suma1Int+=Suma1*9;
            Suma2Int+=Suma2*5;
          END;

       6: BEGIN
            EVALUATE(Suma1,COPYSTR(vTXTNumCuenta,6,1));
            EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,16,1));
            Suma1Int+=Suma1*7;
            Suma2Int+=Suma2*10;
          END;

       7: BEGIN
            EVALUATE(Suma1,COPYSTR(vTXTNumCuenta,7,1));
            EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,17,1));
            Suma1Int+=Suma1*3;
            Suma2Int+=Suma2*9;
          END;

       8: BEGIN
            EVALUATE(Suma1,COPYSTR(vTXTNumCuenta,8,1));
            EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,18,1));
            Suma1Int+=Suma1*6;
            Suma2Int+=Suma2*7;
          END;

       9: BEGIN
            EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,19,1));
            Suma2Int+=Suma2*3;
          END;

       10:  BEGIN
              EVALUATE(Suma2,COPYSTR(vTXTNumCuenta,20,1));
              Suma2Int+=Suma2*6;
            END;
     END;
  END;
//Primer dígito de control entidad+sucursal
  Parc1:=0;
  Parc1:= 11 - (Suma1Int MOD 11);
  IF Parc1 > 9 THEN
    Parc1:=11 - Parc1;

//Segundo dígito de control Numero Cuenta
  Parc2:=0;
  Parc2:=11 - (Suma2Int MOD 11);
  IF Parc2 > 9 THEN
    Parc2:=11 - Parc2;

  IF (Digit1 = Parc1) AND (Digit2 = Parc2) THEN BEGIN
  END
  ELSE BEGIN
    ERROR('Número cuenta erroneo, no corresponde el DC: %1%2',Parc1,Parc2);
  END;
END;

martes, 4 de octubre de 2011

Registro dll desde .net c sharp

voy a intentar explicar un poco como registrar una dll de c sharp en un equipo para que desde navision se le pueda llamar, ya se ha explicado como crear una dll cuyos métodos sean visibles desde navision ahora el siguiente paso es registrarla para que esta sea operativa.

yo me he inclinado por añadir un proyecto de instalación en la solución donde hemos creado la aplicación, ir al equipo donde queremos instalarlo y al ejecutarlo nos copia la dll junto con el tlb que se genera en la carpeta que queremos normalmente en c:\windows\system32 y luego con el comando regasm del framework correspondiente registraríamos estas dll.

1 Creación del proyecto de instalación.


Lo primero es agregar un nuevo proyecto a la solución. Asegurarse de seleccionar la opción del asistente para proyectos de instalación.







Se elige el nombre que se quiera y al aceptar, se lanza el Wizard. Después de la pantalla de bienvenida, pide el entorno. Lo normal es seleccionar Windows



Después pedirá que se indique lo que se quiere incluir en el paquete. Indicar que queremos el resultado principal del proyecto de la DLL.




Después hay que indicar si se quiere añadir algún archivo complementario y ya termina.
El solo ya detecta como recurso imprescindible que tiene que estar el Framework en el equipo en el que lo vayas a instalar.

IMPORTANTE:

En la parte superior del explorador de soluciones, se mostrará una serie de botones. El primero de la izquierda da acceso al sistema de archivos para que se indique dónde instalar la DLL.





Seleccionar carpeta de la aplicación, y en las propiedades que se muestran, en DefaultLocation, indicar la ruta de la carpeta System32.











2 Registro de la Dll

Abririamos una ventana de Ms-dos y ejecutaríamos algo así:

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\regasm.exe C:\windows\System32\fichero.dll /tlb:C:\Windows\System32\Fichero.tlb /codebase /verbose

La primera parte:
{C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\regasm.exe} esto depende del framework con en el que hayamos realizado la aplicación