Conversion petit code C vers VBA
Bonjour,
Pourriez-vous m'aider pour la conversion de ce code C vers VBA?
if (YY - CURRENT_YEAR >= 51)
yyyy = 1900 + YY;
else if (YY - CURRENT_YEAR > -50)
yyyy = 2000 + YY;
else
yyyy = 2100 + YY;
Si je ne fais pas d'erreur
CURRENT_YEAR = Year(Now) en VBA
Voici ce que j'ai essayé:
Sub test()
YY = 48
If (YY - Year(Now)) And (YY >= 51) Then
YYYY = (1900 + YY)
'Debug.Print YY
'Debug.Print YY >= 51
'Debug.Print YYYY
ElseIf (YY - Year(Now)) And (YY > -50) Then
YYYY = (2000 + YY)
'Debug.Print YY
'Debug.Print YY > -50
'Debug.Print YYYY
Else
YYYY = (2100 + YY)
'Debug.Print YY
'Debug.Print YYYY
End If
'Debug.Print YYYY
End Sub
Bonjour,
Si j'ai compris la demande:
Sub test()
YY = 48
current_year = Right(Year(Now), 2) + 0
If (YY - current_year >= 51) Then
YYYY = 1900 + YY
ElseIf (YY - current_year > -50) Then
YYYY = 2000 + YY
Else
YYYY = 2100 + YY
End If
End Sub
Bonsoir,
Merci pour votre aide.
Cela semble fonctionner !
Avec YY = 48 j'obtiens, YYYY = 2048
Avec YY = 52 j'obtiens, YYYY = 2052
Avec YY = 80 j'obtiens, YYYY = 1980
Comment savoir quelle année fait passer de 1900 à 2000 et à 2100?
Comment pourrais-je vérifier des dates futures?
Toutes explications sur le fonctionnement de ce code me seraient bien utile.
Bonjour,
J'ai juste repris la logique du code initial en C, il n'est pas de vous?
Un moyen simple de vérifier ça c'est par exemple lister les valeurs que ça retournerait pour les YY allant de 1 à 1000, voici le code légèrement modifié pour le faire:
Sub test()
Dim YY As Integer, current_year As Integer, YYYY As Integer
current_year = Right(Year(Now), 2) + 0
For YY = 1 To 1000
If (YY - current_year >= 51) Then
YYYY = 1900 + YY
ElseIf (YY - current_year > -50) Then
YYYY = 2000 + YY
Else
YYYY = 2100 + YY
End If
Range("A" & YY) = YY
Range("B" & YY) = YYYY
Next YY
End Sub
De 1 à 73 on a les années 2000, de 74 à 99 on a les années 1900, pour 100 et plus on dirait que ça fait juste 2000 + YY
De base quel est l'objectif du code? parce que de ce que je vois on ne peut pas obtenir d'années avant 1974 avec ce code...
Bonjour,
Merci pour votre aide.
Effectivement ce code n'est pas de moi!
L'intégrité du code C:
{
/// \cond
#define XX(d) ( (data[d] - '0') * 10 + (data[d+1] - '0') )
#define YY XX(0)
#define MM XX(2)
#define DD XX(4)
/// \endcond
static const int daysinmonth[] =
{ 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
size_t len, pos;
int yyyy, maxdd;
assert(data);
len = strlen(data);
/*
* Data must be six characters.
*
*/
if (len != 6) {
if (err_pos) *err_pos = 0;
if (err_len) *err_len = len;
return len < 6 ? GS1_LINTER_DATE_TOO_SHORT : GS1_LINTER_DATE_TOO_LONG;
}
/*
* Data must consist of all digits.
*
*/
if ((pos = strspn(data, "0123456789")) != len) {
if (err_pos) *err_pos = pos;
if (err_len) *err_len = 1;
return GS1_LINTER_NON_DIGIT_CHARACTER;
}
/*
* Validate that the month is 01 to 12.
*
*/
if (MM < 1 || MM > 12) {
if (err_pos) *err_pos = 2;
if (err_len) *err_len = 2;
return GS1_LINTER_ILLEGAL_MONTH;
}
/*
* Convert YY to a year using a horizon based on CURRENT_YEAR.
*
*/
if (YY - CURRENT_YEAR >= 51)
yyyy = 1900 + YY;
else if (YY - CURRENT_YEAR > -50)
yyyy = 2000 + YY;
else
yyyy = 2100 + YY;
/*
* Validate the day, accounting for leap years, and permitting "00".
*
*/
maxdd = daysinmonth[MM - 1]; /* Based at 0 */
if (maxdd == -1) /* February; account for leap years */
maxdd = ((yyyy % 4 == 0 && yyyy % 100 != 0) ||
yyyy % 400 == 0) ? 29 : 28;
if (DD > maxdd) {
if (err_pos) *err_pos = 4;
if (err_len) *err_len = 2;
return GS1_LINTER_ILLEGAL_DAY;
}
return GS1_LINTER_OK;
}
Ce code est utilisé pour le vérification de la validité des dates contenue dans des codes-barres.
Ces dates sont toujours sur 6 chiffres.
Le format est YYMMDD donc les années "YY" toujours sur 2 caractères.
La conversion de YY vers YYYY est faite dans le but de permettre le contrôle de la validité des dates.
J'ai déjà codé la vérification pour YYYY sur 4 chiffres "de 2000 à 2099 pour le moment", voir ci-dessous, mais je dois au préalable gérer cette conversion de YY vers YYYY pour au final en faire une fonction.
Sub CheckDate()
Dim strDate As String, dtDate As Date
Dim yyyy As Integer, mm As Integer, dd As Integer
strDate = "21042029" 'Range("A1").Text
yyyy = CInt(Right(strDate, 4))
mm = CInt(Mid(strDate, 3, 2))
dd = CInt(Left(strDate, 2))
If yyyy = 0 Or yyyy < 2000 Or yyyy > 2099 Then
Debug.Print "Date hors plage!"
Exit Sub
End If
If dd < 1 Then
'Apparemment la date du jour n'est pas obligatoire et peut donc être 00, à vérifier!
Debug.Print "Jour ne peut être inférieur à 1."
Exit Sub
End If
If (mm = 1 Or mm = 3 Or mm = 5 Or mm = 7 Or mm = 8 Or mm = 10 Or mm = 12) And dd > 31 Then
Debug.Print "Ce moi n'a que 31 jours!"
Exit Sub
End If
If (mm = 4 Or mm = 6 Or mm = 9 Or mm = 11) And dd > 30 Then
Debug.Print "Ce moi n'a que 30 jours!"
Exit Sub
End If
If yyyy Mod 4 = 0 And yyyy Mod 100 = 0 And yyyy Mod 400 = 0 Then
If mm = 2 And dd > 29 Then
Debug.Print "Ce moi n'a que 29 jours!"
Exit Sub
End If
Else
If mm = 2 And dd > 28 Then
Debug.Print "Ce moi n'a que 28 jours!"
Exit Sub
End If
End If
dtDate = DateSerial(yyyy, mm, dd)
Debug.Print strDate & " = " & dtDate
End Sub
Bonjour,
D'accord,
Et donc avec le code que j'ai fournis pour avoir l'évolution pour YY allant de 1 à 1000, est-ce que les valeurs conviennent? bon du coup j'imagine qu'il faut plutôt regarder de 1 à 99.
Bonsoir,
Votre code semble être OK.
Je n'ai pas su déclencher la condition pour 2100!
Normalement si les 2 premières ne sont pas respectés, mais là ?
Je regarde comment lntegrer votre code a ce que j'ai déjà fait.
Bonjour,
Oui même dans le code d'origine j'ai du mal à voir comment on pourrait obtenir les années 2100...
Bonjour,
J'ai peut-être une piste pour identifier les année 2100 à venir!
Débutant avec VBA, Je ne parviens pas à définir les limites.
Pourriez-vous essayer de m'aider?
' Year(Now) = 2023
' 2023 - 50 => 1973 jusqu'a 1999
' 2023 + 51 => 2074 jusqu'a 2000
Sub test()
yy = 48
'pivot = Year(Now) '2023
pivot = "2023" 'forcer des valeurs pour le test.
current_year = pivot Mod 100
'Debug.Print "pivot = " & pivot
'Debug.Print "current_year = " & current_year
siecle = pivot - current_year
'Debug.Print "siecle = " & siecle
If current_year < 50 Then 'ou 49 ou 51 selon les limites ?????
siecle = siecle - 100
'Debug.Print "siecle 19XX = " & siecle
End If
If (yy - current_year >= 51) Then
YYYY = siecle + yy
'Debug.Print "10XX = " & YYYY
ElseIf (yy - current_year > -50) Then
YYYY = siecle + 100 + yy
'Debug.Print "20XX = " & YYYY
End If
End Sub
Bien cordialement
Bonjour,
Je ne sais pas trop...
Est-ce qu'on ne peut pas plutôt faire comme ça:
si 0 à 23 -> années 2000 car on les a déjà passé, si supérieur à 23, donc à 2023 (l'année en cours), alors ce doit être des années 1900, et quand on arrivera aux années 2100 dans l'année courante, alors on peut avoir les années 2100, ou les années 2000???
Il y a un "range" autour de la date "pivot"
Exemple pour pivot = 2023:
2023 - 50 => 1974 jusqu’à 1999
Soit yy = 74 jusqu’à y = 99
2023 + 51 => 2073 jusqu’à 2000
Soit yy = 0 jusqu’à y = 73
Si pivot change le "range" suit.
C'est ce "range" que j'essaie de définir pour 2100.
Il devrait commencer à la fin de du "range" 2000 soit 2074
Je ne sais pas trop comment coder cela
En fait j'e me suis trompé!
Pour l'année actuelle, 2023!
2023 - 50, couvre de 2023 à 1973
2023 + 51, couvre de 2023 à 2074
Dans 27 ans soit en 2050 la couverture 1900 sera terminée
2050 – 50, couvre de 2050 à 2000
2050 + 51, couvre de 2050 à 2101
C'est là qu'il faut intervenir, ce ne sera pas 2050 + 51, mais 2050 + 49
2050 + 49, couvre de 2050 à 2099
2050 + 50, couvre de 2050 à 2100 on à notre siècle 2100
Reste à coder cela
Je regarde de mon côté, mais si quelqu'un veut essayer !!!
Sinon pour faire plus simple, on ne peut pas simplement toujours se dire qu'on fait année_actuelle - 50 + yy ?
parce que j'ai quand même du mal à voit l'intérêt d'aller plus loin que l'année actuelle + 49 ans
On peu essayer!
comment géreriez-vous?
ça ressemblerait à ça:
Function getDate(yy as Integer) as Integer
getDate = Year(Date) - 50 + yy
End Function
Je l'ai mis dans une fonction pour pouvoir appeler ça plus facilement.
On peut donc écrire par exemple:
Sub test_fonction
MsgBox getDate(50)
End Sub
Qui donne:
![image](https://forum.excel-pratique.com/file/img/1/56447_656c5679aedcb912514198.png)
Avec l'année 2023 comme départ, on peut donc aller de 1973 à 2072. Soit de -50 à +49 par rapport à la date de départ.
Bonsoir,
Merci pour cette exemple !
Au passage petite question!
Dans votre première réponse, sur la ligne de code:
current_year = Right(Year(Now), 2) + 0
Quel est l'utilité de + 0 à la fin ?
Bien cordialement
Bonjour,
C'est une habitude que j'ai pour toujours m'assurer qu'on ait bien un nombre et pas du texte, ce n'était pas vraiment utile ici comme j'avais déclaré current_year comme étant une variable pouvant uniquement stocker des nombres entier, et que la conversion se fait automatiquement. Faire + 0 ça force le code à comprendre qu'on veut un nombre et pas du texte, donc il va chercher à convertir "23" en 23 pour pouvoir l'additionner à 0.
Par défaut la fonction Right() renvoie du texte, donc il faut s'assurer que ça ne reste pas du texte.
Bonsoir,
En repensant a votre 1ère proposition:
Sub test()
YY = 48
current_year = Right(Year(Now), 2) + 0
If (YY - current_year >= 51) Then
YYYY = 1900 + YY
ElseIf (YY - current_year > -50) Then
YYYY = 2000 + YY
Else
YYYY = 2100 + YY
End If
End Sub
J'ai imaginé le scénario suivant
YY = 0 à 99
En considérant les 2 chiffres de droite de l'année en cours
current_year = Right(Year(Now), 2) + 0
Année en cours = 23
Siècle d'avant = 1900
Siècle en cours = 2000
Siècle d'après = 2100
(Si année en cours – 49 est négatif et YY supérieur à 50) = siècle en cours si non siècle d'avant
(Si YY est supérieur ou = 0 et Si YY inférieur ou = 99) = siècle en cours
(Si année en cours - 49 est positif et YY Inférieur à 49) = siècle en cours si non siècle d'après
De là on pourrait appliquer:
Siècle d'avant = 1900
YYYY = 1900 + YY
Siècle en cours = 2000
YYYY = 2000 + YY
Siècle d'après = 2100
YYYY = 2100 + YY
Je ne sais pas trop comment coder "est négatif" et "est positif".
Gros doute aussi sur ma façon de gérer les conditions
J'aurais bien besoin d'aide ?
Voici ce que j'ai tenté:
Sub test()
YY = 5
current_year = Right(Year(Now), 2) + 0
If ((current_year - 49) <= 0 And YY > 50) Then
YYYY = 2000 + YY
'Debug.Print YYYY
Else
YYYY = 1900 + YY
'Debug.Print YYYY
End If
If (YY >= 0 And YY <= 99) Then
YYYY = 2000 + YY
'Debug.Print YYYY
End If
If ((current_year - 49) >= 0 And YY > 50) Then
YYYY = 2000 + YY
'Debug.Print YYYY
Else
YYYY = 2100 + YY
'Debug.Print YYYY
End If
' End If
' End If
Debug.Print YYYY
End Sub
Bonjour,
J'ai tenté de traduire les explications, voici le résultat:
Sub test()
Dim YY As Integer, YYYY As Integer, current_year As Integer, siecle As Integer
YY = 5
current_year = Right(Year(Date), 2) + 0
siecle = Year(Date) - current_year
If current_year - 49 <= 0 Then
If YY > 50 Then
YYYY = siecle + YY
Else
YYYY = siecle - 100 + YY
End If
ElseIf current_year - 49 > 0 Then
If YY < 49 Then
YYYY = siecle + YY
Else
YYYY = siecle + 100 + YY
End If
End If
Debug.Print YY & " / " & YYYY
End Sub
Bonsoir,
Je croix que cette fois c'est bon!
J'avais fait une erreur dans mes explications
(Si année en cours – 50 est négatif et YY inférieur ou = à 50) = siècle en cours, si non siècle d'avant.
(Si année en cours - 50 est positif et YY Supérieur ou = à 50) = siècle en cours si non siècle d'après.
Merci, vous avez fait le gros du travail!
Pouvez-vous me confirmer que ma modification est bonne?
Sub test()
Dim YY As Integer, YYYY As Integer, current_year As Integer, siecle As Integer
YY = 49
'current_year = Right(Year(Date), 2) + 0
current_year = Right((2023), 2) + 0
'siecle = Year(Date) - current_year
siecle = (2023) - current_year
If current_year - 50 <= 0 Then
If YY < 50 Then
YYYY = siecle + YY
Else
YYYY = siecle - 100 + YY
End If
ElseIf current_year - 50 >= 0 Then
If YY < 50 Then
YYYY = siecle + 100 + YY
Else
YYYY = siecle + YY
End If
End If
Debug.Print YY & " => " & YYYY
End Sub