martedì 29 gennaio 2008

Trascinare File e Cartelle sulla nostra applicazione - Utilizzo di DragEnter

DragEnter può essere utilizzato per intercettare il trascinamento di files e cartelle sulla nostra applicazione Windows Forms da Explorer.
La realizzazione è alquanto semplice, si crea un nuovo progetto Windows Forms, si aggiunge un controllo di tipo ListView, si imposta su questo la proprietà "AllowDrop", si aggiunge il gestore dell'evento "DragEnter".
All'oggetto viene passato un array di nomi di file che sono parcheggiati nella ClipBoard, visto che la clipboard può contenere diversi tipi di dati è necessario specificare il tipo ricercato mettendo la enumerazione corretta "DataFormats" nel nostro caso "FileDrop"

All'interno del gestore dell'evento:

C#

string[] filenames = (string[]) e.Data.GetData(DataFormats.FileDrop);
foreach (string s in filenames)
 {
      // Aggiungi Elemento ListView
}

VB.NET

Dim filenames As String() = CType(e.Data.GetData(DataFormats.FileDrop), String())
For Each s As String In filenames
     ‘Aggiungi Elemento ListView
Next

Per ogni elemento "s" ho aggiunto la visualizzazione della relativa icona recuperata tramite una classe "helper" che fa uso di P/INVOKE.
E' possibile, tramite un menu contestuale scegliere LargeIcon o SmallIcon.
Per questioni di visualizzazione di nomi molto lunghi ho preferito lasciare solo il nome del file senza la path a cui appartiene.

Esempio in C#
Esempio VB.NET

domenica 13 gennaio 2008

Preparazione file per flussi Ri.Ba secondo il tracciato CBI

 

La ricevuta bancaria è uno dei metodi di pagamento previsti per regolare i rapporti tra cliente e fornitore.
Il funzionamento è molto semplice, viene prodotto e stampato un tagliando, promemoria della scadenza di un debito.
Alla scadenza viene addebitato il conto del debitore e accreditato il conto del creditore.
Il normale flusso delle operazioni è :

  • L'azienda creditrice prepara il flusso Ri.Ba e lo invia alla banca
  • La banca o l'azienda, a seconda degli accordi stampano ed inviano gli avvisi al cliente
  • Alla scadenza la banca a seconda degli accordi intrapresi prepara un flusso per l'azienda cliente dell'esito di ciascun pagamento

Nell'esempio ho predisposto solamente la creazione del file Ri.Ba da inviare alla banca

Secondo gli accordi presi da banche e aziende clienti per ciascuna tipologia di comunicazione è prevista una struttura particolare che ne descrive le particolarità.

Tutti i flussi sono definiti con righe (records) a lunghezza fissa di 120 caratteri, la prima riga è il record di header del flusso, sostanzialmente contiene Le informazioni generali relative al flusso.

HEADER

Campo Valore Descrizione
Tipo Record IB Valore fisso "IB" come qualificatore flusso Ri.Ba
Mittente Codice SIA Azienda Codice sia dell'azienda Mittente
Ricevente Codice ABI Banca Codice abi della banca incasso Ri.Ba

Come ultima riga del flusso è prevista la presenza di un record di coda che ha lo scopo sostanziale di "validare" gli elementi presenti nel flusso certificando che il flusso è completo.

FOOTER

Campo Descrizione
Tipo Record Valore fisso "EF" come qualificatore di fine flusso
Mittente Codice sia dell'azienda Mittente
Ricevente Codice abi della banca incasso Ri.Ba
Importi Sommatoria degli importi dei documenti Ri.Ba
Numero Righe Conteggio delle righe presenti nel flusso
Numero Ricevute Numero Ri.Ba

Per ogni Ricevuta Bancaria sono previsti 7 records

Tipo Record
14
20
30
40
50
51
70

Ciascuno di questi descrive una parte delle informazioni riguardo il rapporto di credito / debito, chi deve pagare quando e dove.

La descrizione completa del tracciato Ri.Ba Cbi è codificata insieme a tutte le altre convenzioni di flusso nel documento "CBI-RIB-001.doc" scaricabile all'indirizzo Associazione CBI - Standard Tecnici

Per l'interfacciamento con i dati delle Ri.Ba ho utilizzato due tabelle

Tabella Descrizione
TestataDisposizioni Definizione dei dati generali per ciascun flusso, la chiave principale è un numero progressivo che è ridondato nelle righe come prima parte della PK
RigheDisposizioni Dettaglio invio riba, una riga contiene una scadenza la pk è composta dal progressivo invio e da un numero progressivo di riga.
La PK garantisce anche l'ordinamento dei dati nell'estrazione

Tramite il wizard di Visual Studio 2005 ho generato il DataSet tipizzato e i TableAdapters che ho utilizzato nella mia applicazione.

La realizzazione ha comportato la scrittura di un progetto con i moduli principali

Modulo Descrizione
MainForm Form principale dell'applicazione
GeneraDatiRibaForm Form Interfaccia per la creazione dei dati di prova
GeneraFileRibaForm Form Interfaccia creazione file flusso
DatiCbi Classe helper per file flusso

La form principale (MainForm)  contiene

Campo Descrizione
ImageMenu ImageList contenente le icone necessarie al programma
LvMenu Listview che interfaccia mainform con le altre 2 form, nel campo "Tag" dei ListViewItem ho impostato il nome del form da caricare tramite doppio click sull'icona corrispondente
ApriFormByName Metodo che consente di aprire una form con il nome
lvMenu_DoubleClick Gestore dell'evento doppio click sulla listview

 

Evento ApriFormByName

private void ApriFormByName(string formName, string namespaceName)
{
   string fullName = namespaceName;
   try
   {
       if (namespaceName == null)
           fullName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
       if (!fullName.EndsWith("."))
           fullName += ".";
       fullName += formName;
       Type oFormType = Type.GetType(fullName, true, true);
       ((Form)oFormType.GetConstructor(System.Type.EmptyTypes).Invoke(null)).Show();

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message + " " + ex.StackTrace);
    }
}

Evento lvMenu_DoubleClick

private void lvMenu_DoubleClick(object sender, EventArgs e)

{
   string nomeForm = (string)lvMenu.SelectedItems[0].Tag;
            ApriFormByName(nomeForm, null);

}

 

Generazione Dati di Prova

Questa form contiene una normalissima creazione di TestataDisposizioni e RigheDisposizioni con dati "random", nota: i dati sono palesemente falsati proprio perchè non possano in alcun modo ricondurre a situazioni reali. Eventuali utilizzatori in condizioni reali dovranno provvedere in proprio a inserire i dati nel database.

private void CreaDatiRiba()
{
     int righe = 0;
     righe = CheckValore(righeTextBox);
     if (righe <= 0)
        return;
     testataTableAdapter.Fill(dsDati.TestataDisposizioni);
    
     int idTestata = dsDati.TestataDisposizioni.Rows.Count;

     if (idTestata > 0)
     {
        idTestata = (int)dsDati.TestataDisposizioni.Rows[idTestata - 1]["IdInvio"];
     }

     idTestata += 1;

     daticbiDataSet.TestataDisposizioniRow drTestata = (daticbiDataSet.TestataDisposizioniRow)dsDati.TestataDisposizioni.NewRow();
     drTestata.AbiAzienda = rnd.Next(1, 99999);
     drTestata.CabAzienda = rnd.Next(1, 99999);
     dsDati.TestataDisposizioni.Rows.Add(drTestata);
     for (int k = 0; k < righe; k++)
     {
         daticbiDataSet.RigheDisposizioniRow drRighe = (daticbiDataSet.RigheDisposizioniRow)dsDati.RigheDisposizioni.NewRow();     

          dsDati.RigheDisposizioni.Rows.Add(drRighe);
     }
     testataTableAdapter.Update(dsDati.TestataDisposizioni);
     righeTableAdapter.Update(dsDati.RigheDisposizioni);
     MessageBox.Show("Dati generati");

}

 Generazione File flusso Riba

Si tratta di una classe che contiene i campi:

Nome Descrizione
fileButton Sostituisce la label del campo "nome del file" con un clic si apre la finestra di dialogo "SaveFileDialog" che consente di scegliere il nome del file da generare
fileTextBox Gestisce il nome del file
invioComboBox In collegamento con la datatable TestateDisposizioni
generaButton Attiva la creazione del file Ri.Ba

 

Classe DatiCbiRiba

Si tratta di una classe costruita appositamente per fornire una interfaccia tra le tabelle TestataDisposizioni e RigheDisposizioni.
Le uniche cose degne di nota sono i metodi:

Nome Descrizione
RecordIB() Genera il testo del record header
RecordEF() Genera il testo del record footer
Record14() Genera il testo del record 14
Record20() Genera il testo del record 20
Record30() Genera il testo del record 30
Record40() Genera il testo del record 40
Record50() Genera il testo del record 50
Record51() Genera il testo del record 51
Record70() Genera il testo del record 70

 

Avvertenza:

Il flusso generato dal programma non ha mai avuto il "battesimo del fuoco", data la complessità sono convinto che ci siano alcuni (speriamo pochi) errori.
Ringrazio in anticipo se qualcuno farà questa prova e me ne comunicherà il risultato.

 

Riferimenti:

Esempio C#
Esempio VB.NET
Associazione CBI - Standard Tecnici
System.Text Namespace

Linq - Esempio Walkthrough: Manipulating Data (Visual Basic) (LINQ to SQL)

L'esempio MSDN: Walkthrough: Manipulating Data (Visual Basic) (LINQ to SQL)  contiene 2 errori che ne impediscono il funzionamento.

Dopo aver generato il sorgente "Northwind.Vb" tramite il comando "sqlmetal" se si seguono le istruzioni dell'articolo l'istruzione:

' Add the customer to the Customers table.
db.Customers.Add(newCust)

Va cambiata in:

' Add the customer to the Customers table.
db.Customers.InsertOnSubmit(newCust)

più avanti, l'istruzione che aggiorna il database:

db.SubmitChanges()

Va cambiata in:


db.Customers.Context.SubmitChanges()


Powerered with Window Live Writer

mercoledì 2 gennaio 2008

Archivio Sportelli Bancari - Elenco Abi Cab Aggiornato a fine Dicembre 2007

L'archivio sportelli bancari elenco Abi Cab aggiornato a fine dicembre 2007  è disponibile per lo scaricamento a questo indirizzo:
Alcune informazioni sui files:
- campi separati da tabulazione hex: 09
- righe separate dal terminatore di riga windows hex: 0d0a
- intestazione colonne sulla prima riga
Il file TabAbi contiene i dati relativi alle banche.
Il file TabAbiCab contiene le informazioni relative agli sportelli
Nel file TabAbi e TabAbiCab è presente il campo "Aggiornamento" che evidenzia la data di riferimento di validità dei dati.
Tutte le righe di TabAbiCab che NON contengono la data più recente sono da considerarsi relative a sportelli non più attivi o assorbiti da altre banche, tali sportelli sono presenti solo come log dei dati storici, ne è sconsigliato l'utilizzo per nuove emissioni di flussi di comunicazione con le banche.
Questo archivio è da considerarsi frutto di una rielaborazione "amatoriale" dei dati, si declina ogni responsabilità derivante dai danni causati dal suo uso.

Powerered with Window Live Writer