Newsgroup: it.comp.lang.visual-basic
Titolo: Calcolo periodi fra due date

Ciao a tutti,
devo fare una funzione che ha come input una dataInizio e una dataFine e il
tipo di periodo.
A seconda di questo mi devo calcolare tutte le date comprese nel "periodo".
Per spiegarmi meglio i periodi possono essere(*fissi*): Giornaliero,
Mensile, Trimestrale, Semestrale o Annuale. 
Se data inizio fine fossero 01/01/2006 - > 31/12/2006 la mia funzione
dovrebbe tirarmi fuori un vettore:
giornaliero : ogni singola data
mensile : 31/01/2006 - 28/02/2006 .... > 31/12/2006
trimestrale : 31/03/2006 - 30/06/2006 - 30/09/2006 - 31/12/2006
semestrale : 30/06/2006 - 31/12/2006
annuale : 31/12/2006
Avete qualche consiglio su come iniziare a muovermi?
Avevo pensato al DateSerial come base (per trovarmi gli ultimi giorni dei
mesi/trimestri/semestri).
L'intervallo solitamente puň essere su piů anni.
Grazie

 Avete qualche consiglio su come iniziare a muovermi?
A prima botta, partirei dalla prima data del periodo, e comincerei ad
aggiungere con un dateadd l'intervallo richiesto, se il risultato è
all'interno del periodo memorizzo la data, e riaggiungo l'intervallo, se
no esco dal ciclo.
-- 
Salutoni
Sergio
Per rispondere... togli il group dall'indirizzo
Se i tempi non chiedono la tua parte migliore, inventa altri tempi. 
(Baolian, libro II, vv. 16-17)
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 no esco dal ciclo.
Ti ringrazio, non conoscevo la dateadd.
Sto buttando giů la routine, poi vi faccio sapere :)

 Ti ringrazio, non conoscevo la dateadd.
Beh, la somma però la conoscevi, mi auguro...
Alberto
-- 
A questo punto hanno trovato un muro,
un muro duro, molto molto duro,
che siamo noi.

 Beh, la somma però la conoscevi, mi auguro...
Sisi, solo che con le date facevo un po' di casino :)
A chi interessasse incollo la prima bozza_
Devo sistemare una cosa, che se chiedo una data trimestrale e parto tipo da
30/12/2004 mi trova come primo intervallo 28/02 quando invece i trimestri
sono sempre al 31/03.
Comunque controllerò a monte l'input credo.
Il redim messo in un do loop è una cosa "corretta"? O è preferibile fare
diversamente?
Grazie
***
Public Sub IntervalloDate(RetVet() As Date, dataIn$, dataFi$, Periodo%)
'Sub che mi mette in un vettore una serie di date
'comprese nel periodo
Dim DataI As Date
Dim DataF As Date
Dim DateApp As Date
Dim IntervalType As String 'Tipo Intevallo
Dim Number As Long 'Unità intervallo
Dim cont As Integer
If dataIn$ = "" Or dataFi = "" Or Periodo% = 0 Then Exit Sub
Erase RetVet
DataI = CDate(dataIn$) 'La data in input è considerata valida
DataF = CDate(dataFi$)
Select Case Periodo%
  Case 1 'Giorni
    IntervalType = "y"
    Number = 1
  Case 2 'Mesi
    IntervalType = "m"
    Number = 1
  Case 3 'Trimestri
    IntervalType = "m"
    Number = 3
  Case 4 'Semestri
    IntervalType = "m"
    Number = 6
  Case 5 'Anni
    IntervalType = "m"
    Number = 12
End Select
If Periodo% > 1 Then 'se non è giornaliero parto dall'ultimo gg del periodo
  DateApp = DateSerial(Year(DataI), Month(DataI) + Number, 0)
Else
  DateApp = DataI
End If
cont% = 0
Do While DateApp <= DataF
  ReDim RetVet(0 To cont%)
  RetVet(cont%) = DateApp
  DateApp = DateAdd(IntervalType, Number, DateApp)
  If Periodo% > 1 Then 'se non è giornaliero risetto dall'ultimo gg del
mese
    'Altrimenti farebbe 31/01 -> 28/02 -> 28/03 invece di 31/03
    DateApp = DateSerial(Year(DateApp), Month(DateApp) + 1, 0)
  End If
  cont% = cont% + 1
Loop
End Sub

   ReDim RetVet(0 To cont%)
Sostituire con:
ReDim Preserve RetVet(0 To cont%)
:)

"Andrea" <nos...@invalid.invalid> ha scritto nel messaggio

E periodo con un Enum.
Questo a prima vista, poi credo ci siano un bel po' di cose su cui fare 
"refactoring".
Ciao 

 "refactoring".
Infatti a seconda vsta sembra scritto da un programmatore basic di vent'anni 
fa.
Tanto per iniziare, perchè dataIn e dataFi si prendono i soldi e Periodo 
solo una percentuale?
Ciao 

 solo una percentuale?
Dici sul serio? :)
Comunque %=As integer, $= As String
Le date con cui entro sono prese da TXT, quindi sono stringa (ma comunque
quando entro o sono date o sono "")
L'Enum ora guardo che è :)

 Le date con cui entro sono prese da TXT, quindi sono stringa
Le funzioni vanno DECONTESTUALIZZATE!!!
Se lavora su delle date deate devono essere.
Le conversioni le fai fuori!
Magari con una funzione fatta appositamente per il formato in entrata.
Ciao
-- 
Free .Net Reporting Tool - 
http://www.neodatatype.net

 Magari con una funzione fatta appositamente per il formato in entrata.
In effetti hai ragione, renderebbe anche il debug più semplice per trovare
errori.
Solo che in questo caso è una routine particolare in cui entro solo da
un'altra sub.
In effetti di solito faccio per risparmiare codice, convertendo all'interno
della routine la variabile stringa in variabile data
DataI = CDate(dataIn$) 
DataF = CDate(dataFi$)
Altrimenti ogni volta che richiamo la routine devo fare la conversione a
monte.
Come se ho una sub di calcolo a cui passo un ID faccio:
Call Miasub(val(txtID))
Public sub Miasub (ID as Long)
 if id<=0 then exit sub
  ... operazioni
end sub
Anche in questo caso sarebbe meglio richiamare la routine solo se ID è
maggiore di 0? Il fatto è che a volte i controlli sono più complessi, e
facevo per avere il codice più pulito.
Grazie

 DataF = CDate(dataFi$)
CDate e` l'anticamera dell'inferno.
-- 
ciao, hal

 fa.
Sullo Spectrum 64 funziona benissimo.


 CDate e` l'anticamera dell'inferno.
La data stringa che gli passo č preventivamente controllata se valida.
Cosa potrei utilizzare per mettere in una variabile data il contenuto di
una textbox?

 una textbox?
A parte usare il DateTimePicker, l'unica alternativa al CDate è l'uso 
di DateSerial, Val e Mid$.
La differenza è che con CDate la data deve essere nel formato definito 
nel sistema operativo, mentre con Mid$ i vari pezzi devono essere in 
posizioni predefinite.
E' una scelta tua.
Cioè, se l'applicativo deve essere usato solo da italiani, l'unica 
soluzione valida è quella del mid$ (perchè molti, anche in Italia, 
usano sistemi operativi in inglese, per cui ci sarebbe incongruenza fra 
ciò che l'utente digita e ciò che vb interpreta).
Se invece vuoi che l'applicativo si 'autoadegui' all'operatore, 
confidando che il sistema operativo avrà una localizzazione coerente 
con l'utilizzatore, va benissimo anche CDate.
Ciao


 con l'utilizzatore, va benissimo anche CDate.
Per l'applicazione che sto facendo allora va benissimo il CDate allora,
tanto poi in fase di memorizzazione sul DB utilizzo una funzione che
utilizza le mid.
In pratica la data viene visualizzata in quel modo (dd/mm/yyyy), e la
scompongo in quel modo lì. Se non fosse valida sarà "" sempre e comunque
già al lostfocus del campo.
Il Cdate è utilizzato solo in alcune routine per non dover convertire la
data in ddddmmyy per dover fare un confronto maggiore/minore.
Ma per al clientela a cui è rivolto non ci dovrebbero essere problemi.

 Ma per al clientela a cui è rivolto non ci dovrebbero essere problemi.
Non discuto.
Come dicevo, se il tuo sw è destinato ad una utenza internazionale, ha 
un senso anche il CDate.


 confronto. Con quel formato, poi, con il giorno davanti, men che meno.
Ovviameente volevo dire yyyymmdd :P
Poi volevo appunto dire che il cdate *lo uso solo* quando devo fare dei
confronti.
La conversione in stringa č sulla textbox in caricamento/insert/update
Tnx :)

 che vuole firebird cioè 'mm-dd-yyyy'
Realizzata però con la concatenazione di spezzoni ottenuti con Mid$, mi 
auguro, e non con Format$, altrimenti siamo daccapo...
E poi, sei sicuro che FireBird voglia quel formato, e non sia meglio 
yyyymmdd?


 yyyymmdd?
Lo lessi in un manuale di Interbase quando sono entrato a lavorare, testai
che non si sbagliasse fra 01/02 e 02/01, e dato che funzionava non ho
indagato ulteriormente.
Poi apparte i "-" sarebbe la classica notazione inglese, e penso che se la
becchino più o meno tutti i Database...