Solved

PERL : How to evaluate and compare a value from a cell using Spreasheet Paser Excel Module

Posted on 2009-04-10
16
528 Views
Last Modified: 2012-05-06
Hello,

I need to evaluate a value from a field providing an Excel file. I can loaded using Parser Excel Module. The format of the field to evaluate is like 00:00:00 (hh:mm:ss). I just want to do this thing :

(If $(field) < 15 minutes) {action} ===> how can I write this ?

Tell me if you need to see the code, it is just really long !

Thank you for your reply
0
Comment
Question by:papfal
  • 8
  • 4
  • 4
16 Comments
 
LVL 25

Expert Comment

by:lwadwell
ID: 24114214
Hi papfal,

Assuming that the value being returned to perl is in hh:mm:ss format ... you can either method 1. parse the value into minutes and then test that, or 2. compare the text string (this is risky when it isn't the right format).  

See my sample script below.

lwadwell
use strict; 
my @examples = ("00:14:59","00:15:00","01:02:03","00:00:50","0000");
my $inminutes; 
print "METHOD 1\n";
foreach my $field ( @examples ) {
	if ( $field =~ /^(\d{2}):(\d{2}):(\d{2})$/ ) {
		$inminutes = ($1 * 60) + $2 + ($3 / 60);
		if ( $inminutes < 15 ) {
			print "Value $field is less than 15 minutes at $inminutes minutes\n";
		} else {
			print "Value $field is more than 15 minutes at $inminutes minutes\n";
		}
	} else {
		print "Value $field is in wrong format\n"
	}
} 
print "METHOD 2\n";
foreach my $field ( @examples ) {
	if ( $field lt "00:15:00" ) {
		print "Value $field is less than 15 minutes\n";
	} else {
		print "Value $field is more than 15 minutes\n";
	}
}

Open in new window

0
 
LVL 39

Expert Comment

by:Adam314
ID: 24126651
If it is stored internally as a number (not a string)....
I think excel internally stores dates/times as numbers - where the date is stored as epoch days (number of days since a particular day), and hour as a fraction of day (eg: 0.5 = 12 hours).  So if it is stored this way, then 15 minutes is 15/60/24, so you can use this:
if($field < 15/60/24) {

    #do action

}

Open in new window

0
 

Author Comment

by:papfal
ID: 24149840
Hi,

It doesn't work. I tried the three methods as below :

if ( grep /oui/i,$VALEUR{CYCLIQUE} ) {
        if ( length($VALEUR{DUREE}) == 0 ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le cham
p CYCLE ne peut etre vide !");  }
my $inminutes;
#($temp) = $VALEUR{DUREE};   ########## FIRST METHOD #########################
        if ( $VALEUR{DUREE} =~ /^(\d{2}):(\d{2}):(\d{2})$/ ) {
        #if ( grep /^(\d{2}):(\d{2}):(\d{2})$/,$temp ) {
                $inminutes = ($1 * 60) + $2 + ($3 / 60);
                #if ( $VALEUR{DUREE} > 01/60/24 ) {   ############## 2nd METHOD ##########
                if ( $inminutes < 15 ) {
                        @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ CYCLE ne peut etre
inferieur a 15 minutes !");             }
        } else {
                @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le format du champ CYCLE est errone
BORDEL !") ;
        }
}

#$temp = $VALEUR{DUREE}; ################### 3rd METHOD ###########################
#       if ( $temp lt "00:15:00" ) {
#               @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ CYCLE ne peut etre inferieu
r a 15 minutes !");
#       }

I test the $VALEUR($DUREE) value at the end of the script and I have the good one eg. 00:09:00.

1rst METHOD ==> It says wrong format for any value.
2nd METHOD ==> It works but 15/60/24 is consider as one hour. It works for 01:00:00 and upper values
3rd METHOD ==> It match for any value lower or upper than 15 minutes.

Where is the mistake please ?

Thank you for your reply
0
 

Author Comment

by:papfal
ID: 24149871
I did a mistake in the previous message.

#if ( $VALEUR{DUREE} > 01/60/24 ) {   ############## 2nd METHOD ##########

I really did if ( $VALEUR{DUREE} > 15/60/24 ) {  

but the is consider like one hour

thanks
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24149965
What is $VALEUR{DUREE}?  If you do:
    print "\$VALEUR{DUREE}='$VALEUR{DUREE}'\n"
what is the output?
0
 

Author Comment

by:papfal
ID: 24150354
The output for that  is 00:12:00 or 00:18:00 according to value I put in my excel file.
I get good value in my output
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24150452
Method 1 or 3 should work.  Method 2 will not work.
Are you sure the data is exactly as you've shown, no extra spaces or anything?

This example code shows method 1 and 3 with both '00:12:00' and '00:18:00'.

foreach my $value ('00:12:00', '00:18:00') {

	print "Value=$value\n";

	

	##### Method 1

	if($value lt '00:15:00') {

	    print "\tMethod 1: $value: <15 minutes\n";

	}

	else {

		print "\tMethod 1: $value: >=15 minutes\n";

	}

	

	

	##### Method 2

	my $inminutes;

	if($value =~ /^(\d{2}):(\d{2}):(\d{2})$/) {

		$inminutes = ($1 * 60) + $2 + ($3 / 60);

	}

	if($inminutes < 15) {

	    print "\tMethod 2: $value: <15 minutes\n";

	}

	else {

		print "\tMethod 2: $value: >=15 minutes\n";

	}

}

Open in new window

0
 
LVL 25

Expert Comment

by:lwadwell
ID: 24153639
I have had a closer look at the behaviour of Spreadsheet::ParseExcel ... and it seems that it retains the excel formatting in how it shows the data.  See the attached code snippet below that shows some of that behaviour and the output based on the very simple excel file (also shown as picture).

Depending on how you are obtaining the value may be leading to the issue.  Excel, much like lots of applications, keeps date and time as a number expressed as 'days' - where 1 = one day, 1.5 = one and a half days.  To get a raw excel value into minutes you need to multiply it by 24*60.

Can you create a simple spreadsheet based on your original spreadsheets values and run it through the script below and post the results back please?
#!/usr/bin/perl

use strict;

use warnings;

use Spreadsheet::ParseExcel;
 

sub check_value ($) {

    my ($value) = @_;

    

    ##### Method 1

    if($value lt '00:15:00') {

        print "\tMethod 1: $value: <15 minutes\n";

    }

    else {

        print "\tMethod 1: $value: >=15 minutes\n";

    }

        

    ##### Method 2

    my $inminutes = 99999;

    if($value =~ /^(\d{2}):(\d{2}):(\d{2})$/) {

        $inminutes = ($1 * 60) + $2 + ($3 / 60);

    }

    if($inminutes < 15) {

        print "\tMethod 2: $value: <15 minutes\n";

    }

    else {

        print "\tMethod 2: $value: >=15 minutes\n";

    }

}
 

sub cell_handler {
 

    my $workbook    = $_[0];

    my $sheet_index = $_[1];

    my $row         = $_[2];

    my $col         = $_[3];

    my $cell        = $_[4];
 

    printf "Parsed Value: %s; Raw Value: %8.6f, Minute Value: %5.1f\n",

           $cell->value(), 

           $cell->unformatted(), 

           $cell->unformatted()*24*60;

           

    print "-- Checking Parsed Value\n";

    check_value($cell->value());

    

    print "\n";
 

}
 

my $parser = Spreadsheet::ParseExcel->new(

    CellHandler => \&cell_handler,

    NotSetCell  => 1

);
 

my $workbook = $parser->Parse('times.xls');
 
 
 

############

## OUTPUT ##

############

Parsed Value: 00:14:00; Raw Value: 0.009722, Minute Value:  14.0

-- Checking Parsed Value

	Method 1: 00:14:00: <15 minutes

	Method 2: 00:14:00: <15 minutes
 

Parsed Value: 00:16:00; Raw Value: 0.011111, Minute Value:  16.0

-- Checking Parsed Value

	Method 1: 00:16:00: >=15 minutes

	Method 2: 00:16:00: >=15 minutes
 

Parsed Value: 01:00:01; Raw Value: 0.041678, Minute Value:  60.0

-- Checking Parsed Value

	Method 1: 01:00:01: >=15 minutes

	Method 2: 01:00:01: >=15 minutes

Open in new window

excel.JPG
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 

Author Comment

by:papfal
ID: 24155719
Hi,

How can I proceed  to run this. I use cgi for input excel file.
I put values as parameter one by one or must I put the whole excel file like parameter. If Yes how can I proceed ? Sorry I am a newbe in perl development
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24158278
You would open and parse the excel as you are currently doing.  The above code demonstrates 2 ways you can check if the value is less than 15 minutes or not.

Since you didn't include your entire program, we can't help with where to put it - but it will go in your code after you have parsed the excel file (at least part of it) - where you want to compare a cell value to 15 minutes.
0
 

Author Comment

by:papfal
ID: 24159822
OK,
I am going to do that and come back to you as soon as possible.

Thanks
0
 

Author Comment

by:papfal
ID: 24166077
Hi
I m having problems to run the script. I give you my perl script with the excel file in entry.
You c an see the the value in the worksheet "Traitements" of the excel file attached.
Tell me if you need something else to understand the code for example.

Thanks for your help
#!/usr/local/bin/perl

#

#---------------------------------------------

#

# Integre e_sda

#

# - A partir d'un fichier Excel

# V1.1 : creation

#

#---------------------------------------------
 
 

### Mise en place des library ###

use File::Copy;

use DBD::Oracle qw(:ora_types);

use CGI;

use CGI qw/:standard/;  

use DBI qw(:sql_types);

use lib '/u01/app/e_sda/exploit/sources';

use MIME::Lite;

use e_sda::e_sda;

use Spreadsheet::ParseExcel;

use Spreadsheet::ParseExcel::Utility qw(xls2csv);
 
 

### Definition des variables ###

@TIME=localtime(time);

my $HEURE="$TIME[2]h\_$TIME[1]m\_$TIME[0]s";

chomp ($DATE = `date '+le %d/%m/%Y'`);

undef @MESSAGE_SQL;

undef $GEM_SIMU,@MY_ERROR,@MY_EXEC,$COMPTEUR_FEUILLE;

$RAND=int(rand 1000);
 

open(ERRORS_SQL,'/tmp/errors_sql.log');
 

print ERRORS_SQL " test write ";
 
 
 
 

my $dbh = DBI->connect("dbi:Oracle:$SID", $ORA_USER, $ORA_PASSWD, { RaiseError => 1, AutoCommit => 0 });

my $cgi = new CGI;

my $absolute_url  = $cgi->url(-absolute => 1);
 

print $cgi->header('text/html');

print $cgi->start_html(

        -title=>'[eSDA] telechargement d\'une SDA',

    -style => {'src' => ['/style/spinoza.css','/style/eSDA.css','/style/dhtmlwindow.css']},

        -bgcolor=>"",

        -leftmargin=>"3",

        -topmargin=>"3",

        -lang=>'fr-FR'

);
 
 

### Mise en place des parametres ###

       my $LIVRABLE  = $cgi->param('LIVRABLE');

	my $FICH_XLS = $cgi->param('uploaded_file');
 
 

### Extraction du projet ###

if ( $LIVRABLE )

{

$sql="select ID_PROJET,NOM,VERSION,GROUPE,DATE_PROJET,ID_WIC,TYPE_WIC from PROJET_SDA where ID_PROJET=$LIVRABLE";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute ;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; print ERRORS_SQL "errr ::: $MESSAGE"; }

( $ID_PROJET,$NOM,$VERSION,$GROUPE,$DATE_PROJET,$ID_WIC,$TYPE_WIC ) = $dbh->selectrow_array($sql);

if  ( length($ID_PROJET) == 0 ) { $MESSAGE=$sth->err; @MESSAGE_SQL=(@MESSAGE_SQL," ERR - le projet $LIVRABLE n existe pas"); }

$rc  = $sth->finish;

}
 
 
 

### Construction de la page ###

print " <div id=historique STYLE='width: 204px; height: 56px;'><div class='drag-handle'>IMPORTER UNE SDA</div>";

print "<div class='drag-contentarea' style='height:76px'><div class='menu_item'> Projet : $ID_PROJET - $NOM - $VERSION</div>\n";

print "<div class='menu_item'>Groupe utilisateur : $GROUPE</div>\n";

print "<div class='menu_item'>Date creation : $DATE_PROJET</div>\n";

print "<div class='menu_item'>Type projet : $TYPE_WIC</div></div></div>\n";

 #print "<div class='menu_item'>errors  : @MESSAGE_SQL[0] </div></div></div>\n";

print "<div class='sda_item'>";
 

### Download du fichier ###
 

if  ( ! $FICH_XLS )

{

print $cgi->start_multipart_form(-name=>"Tune");

print $cgi->hidden(-name=>'LIVRABLE', -default=>['$LIVRABLE']);

print "<br>Telecharger le fichier excel : <br>";

print $cgi->filefield({-name=>'uploaded_file', -size=>'61'});

print "<br>";

print $cgi->submit('check', 'check');

print $cgi->endform;
 

### TEMPO ###

$LIVRABLE=1;

$SIMU=Y;

}

else

{

#print "fichier : $FICH_XLS\n LIVRABLE :  $LIVRABLE ";
 

### upload du fichier excel ###

open (FDTMP, ">./tmp/tmpfile.xls");

$fh = $cgi->upload('uploaded_file');

binmode FDTMP;

while (<$fh>)

{

print FDTMP ;

}

close FDTMP;
 

### depecage du fichier excel ###
 

chdir "./tmp" or die "\n--- ERR : Impossible de se deplacer dans le repertoire temporaire ---\n";

$FICH_XLS="tmpfile.xls";
 

$oExcel = new Spreadsheet::ParseExcel;

$oBook = $oExcel->Parse($FICH_XLS);
 

my $oWkS;

foreach my $oWkS (@{$oBook->{Worksheet}}) {

$ORDRE ++;

($FEUILLE=$oWkS->{Name}) =~ s/ //g ;

if ( grep /Dates/i,$FEUILLE) { $COMPTEUR_FEUILLE++; $DATES=(xls2csv( ${FICH_XLS}, "${ORDRE}-A1:AC200"))};

if ( grep /Appli/i,$FEUILLE) { $COMPTEUR_FEUILLE++; $APPLI=(xls2csv( ${FICH_XLS}, "${ORDRE}-A1:AC200"))};

if ( grep /Traite/i,$FEUILLE) { $COMPTEUR_FEUILLE++; $JOB=(xls2csv( ${FICH_XLS}, "${ORDRE}-A1:AC2000"))};

if ( grep /Ressources/i,$FEUILLE) { $COMPTEUR_FEUILLE++; $RESSOU=(xls2csv( ${FICH_XLS}, "${ORDRE}-A1:AC200"))};

}
 

if ( $COMPTEUR_FEUILLE != 4 ) {

print "<br>";

print "<div class='sda_error'><font color=black>La E_SDA n\'est pas valide : 1 ou plusieurs des onglets date, application, job et associations ressources ne sont pas présents";

print "</div>";

print "<br> Telecharger le format standard e_sda : <a href=\"http://bt1sssne/vtom/E_SDA_STANDARD_v1.xls\">E_SDA STANDARD</a>";

exit;

}
 
 

@JOB=split /\n/,$JOB;

@APPLI=split /\n/,$APPLI;

@DATES=split /\n/,$DATES;

@RESSOU=split /\n/,$RESSOU;
 

### Relecture de la SDA ###
 

### MISE EN PAGE ###

@LECTURE="";

print "<br><b>--- Mode relecture de la SDA ---</b><br><br>";

print "\n --- Extraction des donnees du fichier excel ---\n";

undef @TEST_DATE;

undef @APPLI_RECENS; undef @JOB_RECENS;
 

# relecture page date #

print "<br>-> Relecture de la page date";

for $LIGNE (grep !/Action/,@DATES)

{

@LIGNE=split ';',$LIGNE;

if ( $LIGNE[0] =~ "Ajout" )     {

if ( grep /$LIGNE[1]/,@DAT_ENVIR ) { @LECTURE_WARNING=(@LECTURE,"\nC | DATE : $LIGNE[1] - Attention : la date est deja presente dans la base et dans l\'environnement $ENVIR -> Date : $LIGNE[1] - elle ne sera pas creee ! "); }

if ( grep /^[Ss]yst/,$LIGNE[2] ) { $LIGNE[2]=systeme; }

if ( grep /^[Aa]uto/,$LIGNE[2] ) { $LIGNE[2]=automatique; }

$DATE{$LIGNE[1]}=$LIGNE[2];

@DATE_REL=(@DATE_REL,$LIGNE[1]);

                                }

}
 
 

# relecture page application

undef $GEOM;

print "<br>-> Relecture de la page application\n";

foreach $LIGNE (@APPLI)

{
 
 

        @LIGNE=split ';',$LIGNE;

        if ( grep/Action/,$LIGNE[0] ) { if ( ! ( grep /[Aa]pplication/,$LIGNE[2]) and grep /[Dd]ate d/,$LIGNE[3] and grep /Heure de d\351but/,$LIGNE[4] and grep /Heure de fin/,$LIGNE[5] and grep /Mode d/,$LIGNE[6] and grep /Activation/,$LIGNE[7] and grep /Cyclique/,$LIGNE[8] and  grep /Cycle/,$LIGNE[9] and grep /[Uu]ser/,$LIGNE[11] and grep /[Mm]achine/,$LIGNE[12] ) {  @LECTURE_ERROR=(@LECTURE_ERROR,"L\'onglet Applications n\'est pas standard E_SDA "); last; } }

        if (  grep/^[Aa]jout$/,$LIGNE[0] or grep/^[Mm]odification$/,$LIGNE[0] and ! (grep /[Pp]oub/,$LIGNE[2]) )

        {
 

	### mise en plce de la geometrie

	$GEOM=$GEOM+50;
 

        if ( grep /[Ii]llim/,$LIGNE[5] ) { $LIGNE[5]=illimite; }

        undef $VALEUR{DUREE};
 

# SFALL : Ajout de la valeur de deplanifier les successeurs dans le hachage 09/04/2009
 

        $VALEUR{ACTION}=$LIGNE[0]; $VALEUR{ENVIR}=$LIGNE[1]; $VALEUR{APPLI}=$LIGNE[2]; $VALEUR{DATE}=$LIGNE[3]; $VALEUR{HEURE_DEBUT}=$LIGNE[4]; $VALEUR{HEURE_FIN}=$LIGNE[5]; $VALEUR{MODE_EXECUTION}=$LIGNE[6]; $VALEUR{CYCLIQUE}=$LIGNE[8]; $VALEUR{DUREE}=$LIGNE[9]; $VALEUR{DEPLANIFICATION}=$LIGNE[10]; $VALEUR{USER}=$LIGNE[11]; $VALEUR{MACHINE}=$LIGNE[12]; $LIGNE[1]{DATE}=$LIGNE[3]; $LIGNE[1]{HEURE_DEBUT}=CONVERT_HEURE($LIGNE[4]); $LIGNE[1]{HEURE_FIN}=CONVERT_HEURE($LIGNE[5]);
 

        # Pour comparaison et reutilisation dans l onglet job

        $LIGNE[2]{DATE}=$TYPE_DATE{$LIGNE[1]};

        $LIGNE[2]{CYCLIQUE}=$LIGNE[8];
 

        # TEST sur les pre requis
 

        foreach $APPLI_RECENS (@APPLI_RECENS)

        {

        if ( grep /${APPLI_RECENS}/,$VALEUR{APPLI} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - Cette application est ajoutee ou modifie plusieurs fois dans la SDA");} else { @APPLI_RECENS=(@APPLI_RECENS,$VALEUR{APPLI}); }

        }
 

        # Recherche par application

        foreach $OBJET ( keys %VALEUR )

        {

        if ( $OBJET =~ "HEURE_DEBUT" or $OBJET =~ "HEURE_FIN" or $OBJET =~ "DUREE" or $OBJET =~ "MODE_EXECUTION" ) { next ; }

        if ( grep /\ /,$VALEUR{$OBJET} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - le champ $OBJET comporte un espace non permis");}

        if ( grep /\W\S/,$VALEUR{$OBJET} and ! ( grep /\:/,$VALEUR{$OBJET} ) and ! ( grep /\-/,$VALEUR{$OBJET} ) and ! ( grep /\351/,$VALEUR{$OBJET} ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - le champ $OBJET contient 1 caractere special"); }

        if ( length($VALEUR{$OBJET}) == 0 ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - le champ $OBJET n\'est pas rempli");}

        }

# SFALL : Ajout test obligatoire champ cycle 09/04/2009
 

	if ( ( grep /oui/i,$VALEUR{CYCLIQUE}) and ( length($VALEUR{DUREE}) == 0 )) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - le champ CYCLE doit etre rempli");} 
 

# Modif SFALL if ( $VALEUR{MODE_EXECUTION} ) { if ( grep /riodique|demande/,$VALEUR{MODE_EXECUTION} ) { ($VALEUR{MODE_EXECUTION}="$+" }  if ( ! ( grep /riodique|demande/,$VALEUR{MODE_EXECUTION} ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - le champ mode execution est mal rempli"); } } else { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - le champ mode execution n est pas rempli");  if ( grep /riodique|demande/,$VALEUR{MODE_EXECUTION} ) { ($VALEUR{MODE_EXECUTION}='$+'); } }
 

# SFALL : respect de la casse du fichier excel champs mode execution le 09042009
 

	if ( $VALEUR{MODE_EXECUTION} ) { if ( grep /riodique/i,$VALEUR{MODE_EXECUTION} ) {$VALEUR{MODE_EXECUTION}="periodique"; } if ( grep /demand/i,$VALEUR{MODE_EXECUTION} ) {$VALEUR{MODE_EXECUTION}="demande"; } if ( ! ( grep /riodique|demande/,$VALEUR{MODE_EXECUTION} ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - l e champ mode execution est mal rempli"); } } else { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - le champ mode execution n est p as rempli");  if ( grep /riodique/i,$VALEUR{MODE_EXECUTION} ) { $VALEUR{MODE_EXECUTION}='periodique'; } if ( grep /demand/i,$VALEUR{MODE_EXECUTION} ) { $VALEUR{MODE_EXECUTION}='demande'; } }
 

        # Mise en place de la fonction de hachage pour comparaison date - job - appli

        $VALEUR{HEURE_DEBUT}=HEURE($LIGNE[4]); $VALEUR{HEURE_FIN}=HEURE($LIGNE[5]);

        if ( $VALEUR{DUREE} ) { $VALEUR{DUREE}=HEURE($VALEUR{DUREE}); }

        $LIGNE[2]{HEURE_DEBUT}=$LIGNE[4]; $LIGNE[2]{HEURE_FIN}=$LIGNE[5];

if ( ! ( grep /$LIGNE[2]/,@APPLI_REL )) { @APPLI_REL=(@APPLI_REL,$LIGNE[2]); }

if ( ! ( grep /$LIGNE[3]/,@DATE_REL )) { print "<br>Recherche type de date dans la base VTOM \n"; @DATE_REL=(@DATE_REL,$LIGNE[3]); 
 

### REQUETE SQL ###

$sql="select type from t_date_vtom where ID_DOMAINE in ($DOMAINE_PROD) and NOM='$LIGNE[3]'";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute ;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; }

( $TYPE_DATE{$LIGNE[2]} ) = $dbh->selectrow_array($sql);

}
 

#--------------------Modif SFALL 09042009------------------------------------------
 

if (@MESSAGE_SQL) {

foreach $ERSQL (@MESSAGE_SQL) { print "<br>$ERSQL"; }

#print "</div>";

}

#----------------------------------------------------------------------------------
 

#if ( length($VALEUR{APPLI})>16 ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - L\'application excede 16 caracteres "); }
 

#if ( ! @LECTURE_ERROR) {
 

$sql="select application from t_application a, t_environnement e where a.ID_DOMAINE in ($DOMAINE_PROD) and e.id_environnement_ora=a.id_environnement_ora and e.environnement='$LIGNE[1]' and application='$LIGNE[2]'";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute ;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; }

( @APP_BASE ) = $dbh->selectrow_array($sql);
 

#}
 

#print " application base : @APP_BASE <br>";
 

        if ( grep/^[Mm]odification$/,$LIGNE[0] and ! ( grep /$LIGNE[2]/,@APP_BASE ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - Attention : l\'application a modifier n\'est pas presente dans la base et l`environnement $ENVIR - elle ne sera pas modifiee !"); }

#        if ( length($VALEUR{APPLI})>16 ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - L\'application excede 16 caracteres "); }

        if ( $VALEUR{HEURE_DEBUT} !~ "[0-4][0-9]:[0-6][0-9]:[0-6][0-9]" ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - L\'Heure de debut n\'est pas une heure valide"); }

        if ( $VALEUR{HEURE_FIN} !~ "[0-4][0-9]:[0-6][0-9]:[0-6][0-9]" and ! (  grep /illimi/,$VALEUR{HEURE_FIN} )) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - L\'Heure de fin n\'est pas une heure valide"); }

        if ( length($VALEUR{DUREE}) != 0 and $VALEUR{DUREE} !~ "[0-4][0-9]:[0-6][0-9]:[0-6][0-9]" ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - la dur\351e du cycle n\'est pas une heure valide"); }

        # pas d horaire illimite sur une appli cyclique

        if ( grep /[Oo]ui/,$VALEUR{CYCLIQUE} and grep /illimi/,$VALEUR{HEURE_FIN} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - Un horaire illimite ne peut etre implemente dans une application cyclique"); }

        # pas d horaire illimte sur une date systeme

        if ( grep /illimi/,$VALEUR{HEURE_FIN} and grep /[Ss]yst/,$TYPE_DATE{$LIGNE[2]} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - Un horair e illimite ne peut etre implemente sur une date systeme"); }
 

### insertion dans la base de donnees ##

if ( grep/^[Aa]jout$/,$LIGNE[0] or grep/^[Mm]odification$/,$LIGNE[0] or grep/^[Ss]uppression/,$LIGNE[0] ) {  

undef $ID_APPLICATION_ORA; undef $APPLICATION_EXIST;
 

### mise en place de la sequence application

$sql_seq="select SEQUENCE_APPLICATIONESDA.nextval from dual";

my $sth =$dbh -> prepare ($sql_seq) ;

my $rc = $sth -> execute ;

( $SEQUENCE_APPLI ) = $dbh->selectrow_array($sql_seq);
 

# recherche de l'id de l'application

$sql="select id_application_ora from t_application a, t_environnement e where a.ID_DOMAINE in ($DOMAINE_PROD) and e.id_environnement_ora=a.id_environnement_ora and e.environnement='$VALEUR{ENVIR}' and application='$VALEUR{APPLI}'";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute ;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; }

( $ID_APPLICATION_ORA ) = $dbh->selectrow_array($sql);
 

# recherche si l application est deja modifie dans le projet
 

$sql="select application from t_application_esda where id_projet='$LIVRABLE' and environnement='$VALEUR{ENVIR}' and application='$VALEUR{APPLI}'";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute ;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; }

( $APPLICATION_EXIST ) = $dbh->selectrow_array($sql);

###print " APPLICATION_EXIST : $APPLICATION_EXIST<br>";
 

### mise en place de la queue

$MACHINE_TEMPO=substr($VALEUR{MACHINE},0,5);

print " machine tempo => $MACHINE_TEMPO";

if ( grep /$MACHINE_TEMPO/,@MACH_WINDOW ) { $QUEUE="queue_wnt1"; } else { $QUEUE="queue_ksh"; }
 
 

if ( ! ( $APPLICATION_EXIST ) )

{

	if  ( $ID_APPLICATION_ORA )

	{

		$sql_insert="insert into t_application_esda (ID_PROJET,ENVIRONNEMENT,APPLICATION,ACTIVATION,PERIODICITE,CYCLIQUE,CYCLE,MACHINE,QUEUE,UTILISATEUR,DEPLANIFICATION,DATE_VTOM,HEURE_DEBUT,HEURE_FIN,ACTION,ID_APPLICATION_ESDA,GEOMETRIE,ID_APPLICATION_ORA) values ('$LIVRABLE','$VALEUR{ENVIR}','$VALEUR{APPLI}','job','$VALEUR{MODE_EXECUTION}','$VALEUR{CYCLIQUE}','$VALEUR{DUREE}','$VALEUR{MACHINE}','$QUEUE','$VALEUR{USER}','$LIGNE[10]','$VALEUR{DATE}','$VALEUR{HEURE_DEBUT}','$VALEUR{HEURE_FIN}','$LIGNE[0]','$SEQUENCE_APPLI','180x25+$GEOM+50','$ID_APPLICATION_ORA')";

	}

	else 

	{

	$sql_insert="insert into t_application_esda (ID_PROJET,ENVIRONNEMENT,APPLICATION,ACTIVATION,PERIODICITE,CYCLIQUE,CYCLE,MACHINE,QUEUE,UTILISATEUR,DEPLANIFICATION,DATE_VTOM,HEURE_DEBUT,HEURE_FIN,ACTION,ID_APPLICATION_ESDA,GEOMETRIE,ID_APPLICATION_ORA) values ('$LIVRABLE','$VALEUR{ENVIR}','$VALEUR{APPLI}','job','$VALEUR{MODE_EXECUTION}','$VALEUR{CYCLIQUE}','$VALEUR{DUREE}','$VALEUR{MACHINE}','$QUEUE','$VALEUR{USER}','$LIGNE[10]','$VALEUR{DATE}','$VALEUR{HEURE_DEBUT}','$VALEUR{HEURE_FIN}','$LIGNE[0]','$SEQUENCE_APPLI','180x25+$GEOM+50','-1')"; 

	}

}

else

{

	$sql_insert="update t_application_esda set PERIODICITE='$VALEUR{MODE_EXECUTION}',CYCLIQUE='$VALEUR{CYCLIQUE}',CYCLE='$VALEUR{DUREE}',MACHINE='$VALEUR{MACHINE}',UTILISATEUR='$VALEUR{USER}',DEPLANIFICATION='$LIGNE[10]',DATE_VTOM='$VALEUR{DATE}',HEURE_DEBUT='$VALEUR{HEURE_DEBUT}',HEURE_FIN='$VALEUR{HEURE_FIN}',ACTION='$LIGNE[0]',QUEUE='$QUEUE' where ID_PROJET='$LIVRABLE' and ENVIRONNEMENT='$VALEUR{ENVIR}' and APPLICATION='$VALEUR{APPLI}'";

}	
 

my $sth =$dbh -> prepare ($sql_insert) ;

my $rc = $sth -> execute ;
 

}
 
 
 

        }
 

        if ( grep/^[Ss]uppression$/,$LIGNE[0] and ! ( grep /$LIGNE[2]/,@APP_BASE ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"APPLICATION : $VALEUR{APPLI} - Attention : l \'application a supprimer n\'est pas presente dans la base et l`environnement $ENVIR - elle ne sera pas suprimee !"); }

}
 
 
 
 

### Relecture de la page job ###

print "<br>-> Relecture de la page job \n";

undef $GEOM; 
 

foreach $LIGNE (@JOB)

{
 

### REINITIALISATION PARAMETRES

undef $PARAM;
 

#SFALL : 10/04/2009 Rajout des champs Calendrier et Activation pour standardisation complete du fichier Excel
 

        @LIGNE=split ';',$LIGNE;

        if ( grep/Action/,$LIGNE[0] ) { if ( ! ( grep /Environnement/,$LIGNE[1] and grep /Application/,$LIGNE[2] and grep/Traitement/,$LIGNE[3] and grep /[Ss]cript/,$LIGNE[4] and grep /Heure\ de\ d/,$LIGNE[5] and grep /Heure\ de\ fin/,$LIGNE[6] and grep /Mode\ d/,$LIGNE[7] and grep /calendrier/i,$LIGNE[8] and grep /[Cc]yclique/,$LIGNE[9] and grep /[Cc]ycle/,$LIGNE[10] and grep /activation/i,$LIGNE[11] and grep /User/,$LIGNE[12] and grep /Machine/,$LIGNE[13] and grep /[Dd]\351planifier/,$LIGNE[14] and grep /Mettre\ l/,$LIGNE[15] and grep /Bloquer\ l/,$LIGNE[16] and grep /[Pp]aram/,$LIGNE[17] ) )  { @LECTURE_ERROR=(@LECTURE_ERROR,"L\'onglet Job n\'est pas standard E_SDA"); last; } }
 

        if (  grep/^[Aa]jout$/,$LIGNE[0] or grep/^[Mm]odification$/,$LIGNE[0] and ! (grep /[Pp]oub/,$LIGNE[1]) and ! (grep /[Pp]oub/,$LIGNE[2]) )

        {
 

	# Incrementation de la geometrie

	$GEOM=$GEOM+50;
 

# SFALL : 10/04/2009 - Ajout du controle du champ calendrier
 

        if ( grep /[Ii]llim/,$LIGNE[6] ) { $LIGNE[6]=illimite; }

        undef $VALEUR{APP_HEURE_DEBUT}; undef $VALEUR{APP_HEURE_FIN}; undef $VALEUR{DATE}; undef $VALEUR{DUREE};

        $VALEUR{ACTION}=$LIGNE[0]; $VALEUR{ENVIR}=$LIGNE[1]; $VALEUR{APPLI}=$LIGNE[2]; $VALEUR{JOB}=$LIGNE[3]; $VALEUR{SCRIPT}=$LIGNE[4]; $VALEUR{HEURE_DEBUT}=$LIGNE[5]; $VALEUR{HEURE_FIN}=$LIGNE[6]; $VALEUR{MODE_EXECUTION}=$LIGNE[7]; $VALEUR{CALENDRIER}=$LIGNE[8]; $VALEUR{CYCLIQUE}=$LIGNE[9]; $VALEUR{DUREE}=$LIGNE[10]; $VALEUR{USER}=$LIGNE[12]; $VALEUR{MACHINE}=$LIGNE[13]; $VALEUR{PLANIFICATION}=$LIGNE[14]; $VALEUR{APPLI_ERR}=$LIGNE[15]; $VALEUR{BLOCAGE}=$LIGNE[16];
 

        # Test sur les pre requis
 

        if ( grep /$VALEUR{APPLI}\-$VALEUR{JOB}$/,@{JOB_RECENS} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nC | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - Ce job est ajoute ou modifie plusieurs fois dans la SDA");} else { @JOB_RECENS=(@JOB_RECENS,"$VALEUR{APPLI}-$VALEUR{JOB}");

###print " \@JOB_RECENS => @JOB_RECENS ";

}

        # Recherche par job

        foreach $OBJET ( keys %VALEUR )

        {

        if ( $OBJET =~ "HEURE_DEBUT" or $OBJET =~ "HEURE_FIN" or $OBJET =~ "DUREE" or $OBJET =~ "MODE_EXECUTION" or $OBJET =~ "DATE" ) { next ; }

        if ( grep /\ /,$VALEUR{$OBJET} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ $OBJET comporte un espace non permis"); }

        if ( grep /\W\S/,$VALEUR{$OBJET} and ! ( grep /\-/,$VALEUR{$OBJET} ) ) {

	if ( ($OBJET =~ "SCRIPT" ) and ! ( grep /\./,$VALEUR{$OBJET} ) and ! ( grep /\//,$VALEUR{$OBJET}) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ $OBJET contient 1 caractere special"); }

	elsif ( $OBJET =~ "MODE_EXECUTION" and ! ( grep /\351/,$VALEUR{$OBJET} ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ $OBJET contient 1 caractere special");  }

	elsif ( $OBJET !~ "MODE_EXECUTION" and $OBJET !~ "SCRIPT" and $OBJET !~ "CALENDRIER" and ! ( grep /\ /,$VALEUR{$OBJET} ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB}- le champ $OBJET contient 1 caractere special"); } }

        if ( length($VALEUR{$OBJET}) == 0 ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ $OBJET n\'est pas rempli");}

        }
 

# SFALL : 10/04/2009 - Obligation de remplir le champs cycle lorsque le job est cyclique. 

# SFALL : Imposer une valeur minimale de 15 minutes pour le cycle
 

	if (  grep /oui/i,$VALEUR{CYCLIQUE}  and ( length($VALEUR{DUREE} ) == 0 )) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ CYCLE ne peut etre vide !");}
 
 

#if ( grep /oui/i,$VALEUR{CYCLIQUE} ) { 

 #	if ( length($VALEUR{DUREE}) == 0 ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ CYCLE ne peut etre vide !");	}

#my $inminutes;

#($temp) = $VALEUR{DUREE};

#	if ( $VALEUR{DUREE} =~ /^(\d{2}):(\d{2}):(\d{2})$/ ) {  

	#if ( grep /^(\d{2}):(\d{2}):(\d{2})$/,$temp ) {

#		$inminutes = ($1 * 60) + $2 + ($3 / 60);

		#if ( $VALEUR{DUREE} > 01/60/24 ) {

#		if ( $inminutes < 15 ) { 

#			@LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ CYCLE ne peut etre inferieur a 15 minutes !");		}    

#	} else { 

#		@LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le format du champ CYCLE est errone BORDEL !") ;

#	}

#}
 

#$temp = $VALEUR{DUREE};

#	if ( $temp lt "00:15:00" ) {

#		@LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ CYCLE ne peut etre inferieur a 15 minutes !");

#	}
 

# SFALL : 09/04/2009 regroupement des tests et limitation champ mode execution
 

        if ( $VALEUR{MODE_EXECUTION} ) {  if ( grep /riodique/i,$VALEUR{MODE_EXECUTION} ) { $VALEUR{MODE_EXECUTION}="periodique"; } if ( grep /demand/i,$VALEUR{MODE_EXECUTION} ) { $VALEUR{MODE_EXECUTION}="demande"; } if ( ! ( grep /riodique|demande/,$VALEUR{MODE_EXECUTION} ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ mode execution est mal rempli"); } } else { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB}- le champ mode execution n est pas rempli"); }
 
 

        # Mise en place de la fonction de hachage pour comparaison date - job - appli

        $VALEUR{HEURE_DEBUT}=HEURE($LIGNE[5]); $VALEUR{HEURE_FIN}=HEURE($LIGNE[6]);

        if ( $VALEUR{DUREE} ) { $VALEUR{DUREE}=HEURE($VALEUR{DUREE}); }

        $LIGNE[3]{HEURE_DEBUT}=$LIGNE[5]; $LIGNE[3]{HEURE_FIN}=$LIGNE[6]; $LIGNE[3]{BLOCAGE}=$LIGNE[17]; $LIGNE[3]{APPLI}=$LIGNE[2];
 

### REQUETE SQL ###

$sql="select job from t_job j,t_application a,t_environnement e where a.ID_DOMAINE in ($DOMAINE_PROD) and j.id_environnement_ora=e.id_environnement_ora and a.id_environnement_ora=j.id_application_ora and e.environnement='$LIGNE[1]' and a.application='$LIGNE[2]'";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; }

( @JOB_BASE ) = $dbh->selectrow_array($sql);

        # TEST sur les pre requis

        if ( grep/^[Mm]odification$/,$LIGNE[0] and ! ( grep /$LIGNE[2]/,@JOB_BASE ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nC | JOB : $VALEUR{APPLI}/$VALEUR{JOB} -  Attention : le job a modifier n\'est pas present dans la base et l\`environnement $ENVIR - il ne sera pas modifie !"); }

        if ( length($VALEUR{JOB})>16 ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nC | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le job excede 16 caracteres "); }

        if ( $VALEUR{HEURE_DEBUT} !~ "[0-4][0-9]:[0-6][0-9]:[0-6][0-9]" ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - L\'Heure de debut n\'est pas une heure valide ou contient un espace"); }

	if ( $VALEUR{HEURE_FIN} !~ "[0-4][0-9]:[0-6][0-9]:[0-6][0-9]" and ! (  grep /illimi/,$VALEUR{HEURE_FIN} )) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - l\'Heure de fin n\'est pas une heure valide ou contient un espace"); }

        if ( length($VALEUR{DUREE}) != 0 ) { $VALEUR{DUREE}=HEURE($LIGNE[10]); if ( $VALEUR{DUREE} !~ "[0-4][0-9]:[0-6][0-9]:[0-6][0-9]" ) { @LECTURE_ERROR=(@LECTURE,"\nM | APPLICATION : $VALEUR{APPLI} - la dur\351e du cycle n\'est pas une heure valide"); } }

	if ( grep /[Oo]ui/,$VALEUR{BLOCAGE} and $VALEUR{APPLI}{DATE} =~ systeme ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - On ne peut bloquer une date d\'exploitation systeme"); }

        if ( grep /[Oo]ui/,$VALEUR{CYCLIQUE} and grep /[Oo]ui/,$VALEUR{APPLI}{CYCLIQUE} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - On ne peut mettre un job cyclique pour une application cyclique"); }

        if ( length($VALEUR{DUREE}) != 0 and $VALEUR{DUREE} !~ "[0-4][0-9]:[0-6][0-9]:[0-6][0-9]" ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | APPLICATION : $VALEUR{APPLI} - la dur\351e du cycle n\'est pas une heure valide"); }
 

        # comparaison heure job/appli

        if ( ! ( grep /$VALEUR{APPLI}/,@APPLI_REL )) {

                if ( length ( $VALEUR{APP_HEURE_DEBUT} ) == 0 and length ( $VALEUR{APP_HEURE_FIN} ) == 0 )

                { 
 
 

print "<br>-  Recherche heures application dans la base VTOM";

### REQUETE SQL ###

$sql="select heure_debut,heure_fin from t_application a,t_environnement e where a.ID_DOMAINE in ($DOMAINE_PROD) and a.id_environnement_ora=e.id_environnement_ora and e.environnement='$LIGNE[1]' and a.application='$LIGNE[2]'";

print "<br> $sql";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; }

( $LIGNE[1]{HEURE_DEBUT},$LIGNE[1]{HEURE_FIN} ) = $dbh->selectrow_array($sql);
 

                @APPLI_REL=(@APPLI_REL,$VALEUR{APPLI});

                }

        }
 
 

        # pas d horaire illimite sur appli/job cyclique

        if ( grep /[Oo]ui/,$VALEUR{CYCLIQUE} and grep /illimi/,$VALEUR{HEURE_FIN} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - Un horaire de job illimite ne peut etre implemente dans un job cyclique"); }

        if ( grep /[Oo]ui/,$VALEUR{APPLI}{CYCLIQUE} and grep /illimi/,$VALEUR{HEURE_FIN} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - Un horaire de job illimite ne peut etre implemente dans une application cyclique"); }

        # pas d horaire illimte sur une date systeme

        if ( grep /illimi/,$VALEUR{HEURE_FIN} and $VALEUR{APPLI}{DATE} =~ systeme ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - Un horaire de job illimite ne peut etre implemente sur une date systeme"); }
 
 

        $VALEUR{HEURE_DEBUT_REF}=$VALEUR{HEURE_DEBUT};

        $VALEUR{HEURE_FIN_REF}=$VALEUR{HEURE_FIN};

        $VALEUR{HEURE_DEBUT}=CONVERT_HEURE($VALEUR{HEURE_DEBUT});

        $VALEUR{HEURE_FIN}=CONVERT_HEURE($VALEUR{HEURE_FIN});

        if ( length ( $LIGNE[2]{HEURE_FIN} ) != 0 ) { $VALEUR{APP_HEURE_FIN}=CONVERT_HEURE($LIGNE[2]{HEURE_FIN}); }

        if ( length ( $LIGNE[2]{HEURE_DEBUT} ) != 0 ) { $VALEUR{APP_HEURE_DEBUT}=CONVERT_HEURE($LIGNE[2]{HEURE_DEBUT}); }
 
 

        if ( length ( $VALEUR{APP_HEURE_DEBUT} ) != 0 and $VALEUR{HEURE_DEBUT} < $VALEUR{APP_HEURE_DEBUT} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nm | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - l\'horaire de d\351but du job est ant\351rieur \340 l\'horaire de d\351but de l\'application"); }

        if ( length ( $VALEUR{APP_HEURE_FIN} ) != 0 and $VALEUR{HEURE_FIN} > $VALEUR{APP_HEURE_FIN} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nm | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - l\'horaire de fin du job est sup\351rieur \340 l'horaire de fin de l\'application"); }
 

        if ( $VALEUR{HEURE_FIN} > 86359  and  $VALEUR{APPLI}{DATE} =~ systeme ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nm | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - l\'horaire de fin du job ne doit pas exceder 24 h pour une date systeme"); }
 

        }
 

        if ( grep/^[Ss]uppression$/,$LIGNE[0] and ! ( grep /$LIGNE[2]/,@JOB_BASE ) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nC | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - Attention : le job a supprimer n est pas present dans la base et l environnement $ENVIR - il ne sera pas supprimee ! "); }
 
 

###print "---------fin--------------"; exit ;

### Mise en place de parametres
 

# SFALL : 10/04/2009 ==> Proscription des sharp dans les parametres
 

        if ( $LIGNE[17] )

        {

                for ($i=17;$i<28;$i++)

                {

                        if  ( length ($LIGNE[$i]) == 0  ) { $PARAM =~ s/^#//g; last ; }

			if ( grep /\#/,$LIGNE[$i] ) { $j = ($i - 16); @LECTURE_ERROR=(@LECTURE_ERROR,"\nC | PARAM $j : Ne pas mettre de \# dans les parametres ! "); } 

                	$PARAM="$PARAM\#$LIGNE[$i]";

                }

        }
 
 

if ( grep/^[Aa]jout$/,$LIGNE[0] or grep/^[Mm]odification$/,$LIGNE[0] or grep/^[Ss]uppression/,$LIGNE[0] ) {

undef $ID_JOB_ORA; undef @JOB_EXIST;
 

# recherche de l'id  du job

$sql="select id_job_ora from t_application a, t_environnement e , t_job j where a.ID_DOMAINE in ($DOMAINE_PROD) and e.id_environnement_ora=a.id_environnement_ora and e.environnement='$VALEUR{ENVIR}' and j.id_application_ora=a.id_application_ora and a.application='$VALEUR{APPLI}' and job='$VALEUR{JOB}'";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute ;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; }

( $ID_JOB_ORA ) = $dbh->selectrow_array($sql);
 

# recherche si l application est deja modifie dans le projet
 

$sql="select job from t_job_esda where id_projet='$LIVRABLE' and environnement='$VALEUR{ENVIR}' and application='$VALEUR{APPLI}' and job='$VALEUR{JOB}'";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute ;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; }

( $JOB_EXIST ) = $dbh->selectrow_array($sql);
 

###print " JOB_EXIST : $JOB_EXIST<br>";
 

### mise en place de la queue

$MACHINE_TEMPO=substr($VALEUR{MACHINE},0,5);

if ( grep /$MACHINE_TEMPO/,@MACH_WINDOW ) { $QUEUE="queue_wnt1"; } else { $QUEUE="queue_ksh"; }
 

# SFALL : 10/04/2009 ==> Insertion du champ CALENDRIER dans la table t_job_esda
 

if ( ! ( $JOB_EXIST ) )

{

	$sql_seq="select SEQUENCE_JOBESDA.nextval from dual";

	my $sth =$dbh -> prepare ($sql_seq) ;

	my $rc = $sth -> execute ;

	( $SEQUENCE_JOB ) = $dbh->selectrow_array($sql_seq);
 

#______________________Evaluation du format des champs duree cycle_________________________________________________
 

#use strict;

#use warnings;

#use Spreadsheet::ParseExcel;

 

sub check_value ($) {

    #my ($value) = @_;

    my ($value) = $VALEUR{DUREE};

    

    ##### Method 1

    if($value lt '00:15:00') {

        print "<br>-> \tMethod 1: $value: <15 minutes\n";

    }

    else {

        print "<br>-> \tMethod 1: $value: >=15 minutes\n";

    }

        

    ##### Method 2

    my $inminutes = 99999;

    if($value =~ /^(\d{2}):(\d{2}):(\d{2})$/) {

        $inminutes = ($1 * 60) + $2 + ($3 / 60);

    }

    if($inminutes < 15) {

        print "<br>-> \tMethod 2: $value: <15 minutes\n";

    }

    else {

        print "<br>-> \tMethod 2: $value: >=15 minutes\n";

    }

}

 

sub cell_handler {

 

    my $workbook    = $_[0];

    my $sheet_index = $_[1];

    my $row         = $_[2];

    my $col         = $_[3];

    my $cell        = $_[4];

 

    printf "Parsed Value: %s; Raw Value: %8.6f, Minute Value: %5.1f\n",

           $cell->value(), 

           $cell->unformatted(), 

           $cell->unformatted()*24*60;

           

    print "-- Checking Parsed Value\n";

    check_value($cell->value());

    

    print "\n";

 

}

 

my $parser = Spreadsheet::ParseExcel->new(

    CellHandler => \&cell_handler,

    NotSetCell  => 1

);

 

my $workbook = $parser->Parse($FICH_XLS);
 

#______________________FIN TEST FORMAT DUREE__________________________________________________________
 

        if  ( $ID_JOB_ORA ) # SFALL : 10/04/2009 ==> Si l application existe !

        {

		$sql_insert="insert into t_job_esda (ID_PROJET,ENVIRONNEMENT,APPLICATION,JOB,SCRIPT,ACTIVATION,PERIODICITE,CYCLIQUE,CYCLE,MACHINE,QUEUE,UTILISATEUR,DEPLANIFICATION,APPLICATION_ERREUR,DATE_BLOCAGE,HEURE_DEBUT,HEURE_FIN,PARAMETRES,ACTION,id_job_esda,GEOMETRIE,ID_job_ORA) values ('$LIVRABLE','$VALEUR{ENVIR}','$VALEUR{APPLI}','$VALEUR{JOB}','$VALEUR{SCRIPT}','exec','$VALEUR{MODE_EXECUTION}','$VALEUR{CALENDRIER}','$VALEUR{CYCLIQUE}','$VALEUR{DUREE}','$VALEUR{MACHINE}','$QUEUE','$VALEUR{USER}','$VALEUR{PLANIFICATION}','$VALEUR{APPLI_ERR}','$VALEUR{BLOCAGE}','$VALEUR{HEURE_DEBUT_REF}','$VALEUR{HEURE_FIN_REF}','$PARAM','$LIGNE[0]','$SEQUENCE_JOB','180x25+$GEOM+50','$ID_JOB_ORA')";  

	}

	else

	{

		$sql_insert="insert into t_job_esda (ID_PROJET,ENVIRONNEMENT,APPLICATION,JOB,SCRIPT,ACTIVATION,PERIODICITE,CYCLIQUE,CYCLE,MACHINE,QUEUE,UTILISATEUR,DEPLANIFICATION,APPLICATION_ERREUR,DATE_BLOCAGE,HEURE_DEBUT,HEURE_FIN,PARAMETRES,ACTION,id_job_esda,GEOMETRIE,ID_job_ORA) values ('$LIVRABLE','$VALEUR{ENVIR}','$VALEUR{APPLI}','$VALEUR{JOB}','$VALEUR{SCRIPT}','exec','$VALEUR{CALENDRIER}','$VALEUR{CYCLIQUE}','$VALEUR{DUREE}','$VALEUR{MACHINE}','$QUEUE','$VALEUR{USER}','$VALEUR{PLANIFICATION}','$VALEUR{APPLI_ERR}','$VALEUR{BLOCAGE}','$VALEUR{HEURE_DEBUT_REF}','$VALEUR{HEURE_FIN_REF}','$PARAM','$LIGNE[0]','$SEQUENCE_JOB','180x25+$GEOM+50','-1')"; 

	}

}

else

{

	$sql_insert="update t_job_esda set SCRIPT='$VALEUR{SCRIPT}', PERIODICITE='$VALEUR{MODE_EXECUTION}',CALENDRIER='$VALEUR{CALENDRIER}',CYCLIQUE='$VALEUR{CYCLIQUE}',CYCLE='$VALEUR{DUREE}',MACHINE='$VALEUR{MACHINE}',UTILISATEUR='$VALEUR{USER}',DEPLANIFICATION='$VALEUR{PLANIFICATION}',DATE_BLOCAGE='$VALEUR{BLOCAGE}',HEURE_DEBUT='$VALEUR{HEURE_DEBUT_REF}',HEURE_FIN='$VALEUR{HEURE_FIN_REF}',ACTION='$LIGNE[0]',PARAMETRES='$PARAM',QUEUE='$QUEUE' where ID_PROJET='$LIVRABLE' and ENVIRONNEMENT='$VALEUR{ENVIR}' and APPLICATION='$VALEUR{APPLI}' and JOB='$VALEUR{JOB}'";

}

my $sth =$dbh -> prepare ($sql_insert) ;

my $rc = $sth -> execute ;

}

}
 
 

### relecture de la page ressource ###
 

print "<br>-> Relecture de la page ressource \n";
 

# SFALL : 14/04/2009 ==> Rajout des champs Attente, Heure-Limite et Post-Attente dans l onglet Ressources 
 

for $LIGNE (@RESSOU)

{

        @LIGNE=split ';',$LIGNE;

        if ( grep/Action/,$LIGNE[0] ) { if ( ! ( grep /Environnement/,$LIGNE[1] and grep /Application/,$LIGNE[2] and grep/Traitement/,$LIGNE[3] and grep /ressource/,$LIGNE[4] and grep /Type/,$LIGNE[5] and grep /Operateur/,$LIGNE[6] and grep /Valeur/,$LIGNE[7] and grep /Attente/i,$LIGNE[8] and grep /Limite/i,$LIGNE[9] and grep /Post/i,$LIGNE[10]) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"L\'onglet ressource n\'est pas standard E_SDA"); last; } }
 

if (  grep/^[Aa]jout$/,$LIGNE[0] or grep/^[Mm]odification$/,$LIGNE[0] or grep/^[Ss]uppression/,$LIGNE[0] )

{

undef $RES_BASE, $RES_EXIST;
 

         if ( length($LIGNE[0]) == 0  or  length($LIGNE[1]) == 0 or length($LIGNE[2]) == 0 or length($LIGNE[4]) == 0 ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | Ressource : $LIGNE[3] - Attention : cette ressource est mal renseignee dans l\'onglet ressources !"); next; }

        if ( $LIGNE[5] =~ "[Pp]oids" and grep /[Ss]yst/,$LIGNE[2]{DATE} ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | Ressource : $LIGNE[3] - On ne peut attribuer une ressource de type poids sur un JOB ou une APPLI poss\351dant une date systeme"); }
 

# SFALL : 16/04/2009 ==> Modifier le contenu des champs ATTENTE et POST_ATTENTE
 

if (grep /illimi/i,$LIGNE[8] ) { $LIGNE[8] = "ili" };

if (grep /oui/i,$LIGNE[10] ) { $LIGNE[10] = "oui" };

if (grep /non/i,$LIGNE[10] ) { $LIGNE[10] = "non" };
 

# SFALL : 15/04/2009 ==> Imposer une valeur numérique comme valeur attendue pour une ressource type poids.
 

        if ( $LIGNE[5] =~ "[Pp]oids" and ! ( grep /\d/,$LIGNE[7]) ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nM | Ressource : $LIGNE[3] - la valeur attendue doit etre numerique pour une ressource type poids"); }
 

print "<br>-> select environnement,application,job from t_environnement e, t_application a, t_job j, t_declaration_ressource r where '$LIGNE[1]'=e.environnement and '$LIGNE[2]'=a.application and '$LIGNE[3]'=j.job and r.ID_DOMAINE in ($DOMAINE_ PROD) and a.id_application_ora=r.id_application_ora and j.id_job_ora=r.id_job_ora and e.id_environnement_ora=a.id_environnemen t_ora and a.id_application_ora=j.id_application_ora \n";
 

	$sql_res_base="select environnement,application,job from t_environnement e, t_application a, t_job j, t_declaration_ressource r where '$LIGNE[1]'=e.environnement and '$LIGNE[2]'=a.application and '$LIGNE[3]'=j.job and r.ID_DOMAINE in ($DOMAINE_PROD) and a.id_application_ora=r.id_application_ora and j.id_job_ora=r.id_job_ora and e.id_environnement_ora=a.id_environnement_ora and a.id_application_ora=j.id_application_ora";

        my $sth =$dbh -> prepare ($sql_res_base) ;

        my $rc = $sth -> execute ;

	( $RES_BASE ) = $dbh->selectrow_array($sql_res_base);
 

##print "RES_BASE -> $RES_BASE<br>";
 

       if ( $RES_EXIST ) { @LECTURE_ERROR=(@LECTURE_ERROR,"\nm | Ressource : $LIGNE[3] - Attention une ressource est deja allouee sur le traitement ##: $LIGNE[1] $LIGNE[2] -> nom des ressources : $RESSOURCE_EXIST"); }
 
 

# recherche si la resource est deja modifie dans le projet
 

print "<br>-> select nom_ressource from T_DECLARATION_RESSOURCE_ESDA where id_projet='$LIVRABLE' and environnement='$LIGNE[1]' and application='$LIGNE[2]' and job='$LIGNE[3]' and NOM_RESSOURCE='$LIGNE[4]'";
 

$sql="select nom_ressource from T_DECLARATION_RESSOURCE_ESDA where id_projet='$LIVRABLE' and environnement='$LIGNE[1]' and application='$LIGNE[2]' and job='$LIGNE[3]' and NOM_RESSOURCE='$LIGNE[4]'";

my $sth =$dbh -> prepare ($sql) ;

my $rc = $sth -> execute ;

if ( $sth->err ) { $MESSAGE =$sth->err; @MESSAGE_SQL=@MESSAGE_SQL," ERR - $MESSAGE "; }

( $RES_EXIST ) = $dbh->selectrow_array($sql);
 

#print "RES_BASE -> $RES_BASE<br>";
 

if ( ! ( $RES_EXIST ) )

{

print "<br>-> select SEQUENCE_RESSOURCEESDA.nextval from dual";

	$sql_seq="select SEQUENCE_RESSOURCEESDA.nextval from dual";

	my $sth =$dbh -> prepare ($sql_seq) ;

	my $rc = $sth -> execute ;

	( $SEQUENCE_RESSOURCE ) = $dbh->selectrow_array($sql_seq);
 

print "<br>-> insert into T_DECLARATION_RESSOURCE_ESDA (ID_PROJET,ENVIRONNEMENT,APPLICATION,JOB,NOM_RESSOURCE,TYPE,OPERATEUR,VALEUR_PRISE_COMPTE,ATTENTE,HEURE_LIMITE,POST_ATTENTE,ACTION,ID_RESSOURCE_ESDA) values ('$LIVRABLE','$LIGNE[1]','$LIGNE[2]' ,'$LIGNE[3]','$LIGNE[4]','$LIGNE[5]','$LIGNE[6]','$LIGNE[7]','$LIGNE[8]','$LIGNE[9]','$LIGNE[10]','$LIGNE[0]','$SEQUENCE_RESSOURCE')";
 

	$sql_res="insert into T_DECLARATION_RESSOURCE_ESDA (ID_PROJET,ENVIRONNEMENT,APPLICATION,JOB,NOM_RESSOURCE,TYPE,OPERATEUR,VALEUR_PRISE_COMPTE,ATTENTE,HEURE_LIMITE,POST_ATTENTE,ACTION,ID_RESSOURCE_ESDA) values ('$LIVRABLE','$LIGNE[1]','$LIGNE[2]','$LIGNE[3]','$LIGNE[4]','$LIGNE[5]','$LIGNE[6]','$LIGNE[7]','$LIGNE[8]','$LIGNE[9]','$LIGNE[10]','$LIGNE[0]','$SEQUENCE_RESSOURCE')"; 

} 

else

{
 

print "<br>-> update T_DECLARATION_RESSOURCE_ESDA set TYPE = '$LIGNE[5]', OPERATEUR = '$LIGNE[6]', VALEUR_PRISE_COMPTE = '$LIGNE[7]', ATTENTE = '$LIGNE[8]', HEURE_LIMITE = '$LIGNE[9]', POST_ATTENTE = '$LIGNE[10]', ACTION = '$LIGNE[0]' where ID_PROJ ET='$LIVRABLE' and ENVIRONNEMENT = '$LIGNE[1]' and APPLICATION = '$LIGNE[2]' and JOB = '$LIGNE[3]' and NOM_RESSOURCE = '$LIGNE [4]'";

	$sql_res="update T_DECLARATION_RESSOURCE_ESDA set TYPE = '$LIGNE[5]', OPERATEUR = '$LIGNE[6]', VALEUR_PRISE_COMPTE = '$LIGNE[7]', ATTENTE = '$LIGNE[8]', HEURE_LIMITE = '$LIGNE[9]', POST_ATTENTE = '$LIGNE[10]', ACTION = '$LIGNE[0]' where ID_PROJET='$LIVRABLE' and ENVIRONNEMENT = '$LIGNE[1]' and APPLICATION = '$LIGNE[2]' and JOB = '$LIGNE[3]' and NOM_RESSOURCE = '$LIGNE[4]'";

}
 

my $sth =$dbh -> prepare ($sql_res) ;

my $rc = $sth -> execute  ;

#---------------

print $cgi->header('text/html');

print $cgi->start_html(

        -title=>'[eSDA] telechargement d\'une SDA',

    -style => {'src' => ['/style/spinoza.css','/style/eSDA.css','/style/dhtmlwindow.css']},

        -bgcolor=>"",

        -leftmargin=>"3",

        -topmargin=>"3",

        -lang=>'fr-FR'

);
 
 

 #print "<div class='menu_item'>err : $DBI::errstr  </div></div></div>\n";
 

print $cgi->endform;

#---------------

}
 

}
 
 

### ecriture des messages d erreur ###

### Mise a jour de la base de donnees ###

#foreach ( @MESSAGE_SQL )

#{

#print "ERR_SQL : $_";

#}
 

print $cgi->start_td({-class => error, -width=> '130px'});

if ( @LECTURE_ERROR )

{

print "<br>";

print "<div class='sda_error'><font color=black>La SDA n\'est pas valide :";

### rollbackk des actions ###

my $rc  = $dbh->rollback ;

for $ERROR (@LECTURE_ERROR)

{ print "<br>$ERROR"; }

print "</div>";

print "<div class='sda_item'><br> Telecharger le format standard e_sda : <a href=\"http://bt1sssne/vtom/E_SDA_STANDARD_v1.xls\">E_SDA STANDARD</a></div>";

# SFALL : 15/04/2009 ==> Ajout Flag

#print "</div>";

#print "<div class='sda_item'><br> duree : $VALEUR{DUREE}  <a href=\"$VALEUR{DUREE}</a></div>";

}

else

{

print "<br>";

my $rc  = $dbh->commit;

print "<div class='sda_ok'><font color=black>L'integration de la SDA s\' est executee avec succes</div>";

}
 

print "<br><br>";

print button(-name=>'button_name',-value=>'Fermer la fenetre',-onClick=>"parent. close()");

print "<p></div>";
 

print $cgi->end_td;
 

$dbh->disconnect;
 

}
 

close(ERRORS_SQL);
 
 

###exit ;

Open in new window

TEST-ESDA.xls
0
 

Author Comment

by:papfal
ID: 24166083
Hi the column is Traitements/Cycle
0
 
LVL 25

Expert Comment

by:lwadwell
ID: 24166754
This is not very easy for me to debug, I have to take out all of the database work and I must admit I find the language slightly confusing ... is it French or something else?

Anyway ... I think that the values are losing the leading 0 in the time within the script ...

try using this slightly modified regexp:

if($value =~ /^(\d{1,2}):(\d{2}):(\d{2})$/) {
0
 
LVL 25

Accepted Solution

by:
lwadwell earned 500 total points
ID: 24167153
So the final code would be:
if ( $VALEUR{DUREE} =~ /^(\d{1,2}):(\d{2}):(\d{2})$/ ) {

	$inminutes = ($1 * 60) + $2 + ($3 / 60);

	if ( $inminutes < 15 ) {

		@LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le champ CYCLE ne peut etre inferieur a 15 minutes !");		

	}

} else {

	@LECTURE_ERROR=(@LECTURE_ERROR,"\nM | JOB : $VALEUR{APPLI}/$VALEUR{JOB} - le format du champ CYCLE est errone BORDEL !") ;

}

Open in new window

0
 

Author Comment

by:papfal
ID: 24167405
Yes this is french, I am talking to you from Paris. My english is not perfect but I hope you can understand me !

This works ! I get good results after this modifications. Ouffff !!!
But i dont understand the result i get after running the script eg 00:17:00 !? Anyway it works
Thank you
Talk to you soon
Have a nice week !
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now