in reply to Re: Cannot seem to pass number to a function
in thread Cannot seem to pass number to a function

yeah i can track to print a value of 18 as seen in this quick example
#!c:\perl\bin\ -w use Win32::OLE qw(in with); use Win32::OLE::Const 'Microsoft Excel'; use Win32::OLE::Variant; use Win32::OLE::NLS qw(:LOCALE :DATE); use strict; my $configfile = "OleoresinSpreadsheet2.conf"; open (CONFIG,$configfile); my $HPLC_Collum; if(<CONFIG>=~/;;HPLCColumn;;([0-9]+);/){ $HPLC_Collum= $1; } my $Excel = Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application', 'Quit'); my $excelfile = 'F:\Spreadsheet\lab results\COPY GRID MASTER COPY.xls' +; my $Book = $Excel->Workbooks->Open($excelfile); my $WorkBooknumber = 6; my $Sheet = $Book->Worksheets($WorkBooknumber); print($HPLC_Collum); print($Sheet->Cells(6,$HPLC_Collum)->{'Value'});

which leaves me with the following output
Win32::OLE(0.1709) error 0x800a03ec in METHOD/PROPERTYGET "Cells" at C:\Documents and Settings\KHusban +d\Desktop\ New Folder\test2.pl line 20 Can't use an undefined value as a HASH reference at C:\Documents and S +ettings\KH usband\Desktop\New Folder\test2.pl line 20, <CONFIG> line 1. 18

also the problem solves it self if i manualy assign the value such as
$HPLC_Collum = 18
--- Thanks
BlueInk

Replies are listed 'Best First'.
Re^3: Cannot seem to pass number to a function
by ack (Deacon) on Aug 12, 2009 at 16:37 UTC

    The Regex test in your second presentation is not the same as in your original post.

    In your original post you used the regex expression:

    if(/;;HPLCColumn;;([0-9]+);/){ if ($number == 2){ $HPLC_Collum= $1; $number ++; }else { die ; }

    Whereas in your response above you use:

    if(<CONFIG>=~/;;HPLCColumn;;([0-9]+);/){ $HPLC_Collum= $1; }

    Those are not at all the same. Hence, I don't think you're confirming what you think/say you're confirming by the latter example.

    In the former (i.e., the original) case you only set $HPLC_Colum to result of the 1st capture group (i.e., $1) if the value of $number matches the number 2. In the latter case (i.e., in your response) you set the value of $HPLC_Colum unconditionally to the value of $1 from your regex.

    So it looks to me like it is reasonable that you're getting the right answer from the latter but since I can see nowwhere in your original code where you set $number then either $HPLC_Colum never gets set or, presuming it is some global that gets set elsewhere in your code, then I can't tell if you ever get to set $HPLC_Colum.

    Of course, in that original form, if $number doesn't match the number 2 then you would execute the die which I would presume would be obvious. So it looks like $number is set to 2 elsewhere but your regex is not matching so you don't get your match group set like you're expecting.

    I concur with the other responders that you need to be using use strict; and use warnings; to make tracking down these kinds of problems easier. Also, as they suggested, getting familiar with and employing judicious diagnostic print statements to confirm that your variables are getting properly set is most helpful. I would also add that getting familiar with and judiciously using Perl's Debugger can also be helpful...and sometimes more convenient and straight-forward than messing with diagnostic print statements.

    I get these types of challenges frequently and have developed a pretty standard diagnostic strategy to track down the sources of the problems (the strategy is usually a combination of judicuous use of diagnostic prints and the debugger).

    ack Albuquerque, NM
      aha mabey i should have made it more clear as I allso shortened the config file in the second example to only contain one entry. ;;HPLCColumn;;18;
      1. im' using  use strict and i thought the -w tag in  #!c:\perl\bin\ -w was the same as  use warnings
      2.the whole reason for which number is in the first example is so that i make shure that the config file is read in order
      3. the same thing's regardless what example i use 1, or 2, you can output the value caught in the regex directly above where it is is to be called by  $Sheet->Cells(6,$HPLC_Collum)->{'Value'} and it still result's in an error
      Thanks
      BlueInk
Re^3: Cannot seem to pass number to a function
by ig (Vicar) on Aug 12, 2009 at 19:40 UTC

    Maybe $Sheet->Cells() doesn't accept a string but does accept an integer. You could try $Sheet->Cells(6,0+$HPLC_Collum) to test this.

      You Sir are a genius or mabey some one just abnormaly smart any way's thank you very much
      Thanks
      Blueink
      I know this thread is a little old, but after writing literally hundreds of $sheet->Cells($this,$that)->{Value} lines of code, I hit this exact problem. The solution of writing 0+$this works! What makes Perl think these particular variable are strings, when it has treated them as numbers in so much similar code?

        Scalar values are contained in data structures that can accommodate various data types, including integers, numbers, strings and references. Perl converts between these types as necessary, according to how the variable is used.

        I haven't traced the calls all the way through Win32::OLE to the Cells method invocation, but along the way Win32::OLE creates an OLE Variant for each argument passed to the method. In doing so, it looks at the type of data currently in the passed scalar value. The bit of code which, I think, is relevant here is the following:

        /* Scalars */ if (SvIOK(sv)) { V_VT(pVariant) = VT_I4; V_I4(pVariant) = (LONG)SvIV(sv); } else if (SvNOK(sv)) { V_VT(pVariant) = VT_R8; V_R8(pVariant) = SvNV(sv); } else if (SvPOK(sv)) { V_VT(pVariant) = VT_BSTR; V_BSTR(pVariant) = AllocOleStringFromSV(aTHX_ sv, cp); }

        The SvIOK(sv), SvNOK(sv) and SvPOK(sv) macros check whether the scalar value (sv) currently contains an integer, number or string value respectively. You can see that the variant is initialized differently according to the results.

        An OLE variant can contain various data types but the implication of the result reported above is that Excel doesn't convert types as perl does. If it is passed a variant containing an integer value, the call succeeds but if it is passed a variant containing a string that could be converted to the same integer value, it fails. Automatic conversion is one of the strengths/weaknesses of Perl (depending on whether you prefer strongly typed languages). I think it's very convenient myself.

        You can see the type of value in a scalar value by using Devel::Peek. The following test program demonstrates the effect of "0 + $x" and shows that a scalar value can contain an integer and string value at the same time. You might imagine that there is some ambiguity in what should be passed to an OLE method in such a case: a string or an integer?

        use strict; use warnings; use Devel::Peek; my $x = '10'; Dump($x); my $y = $x; Dump($y); my $z = 0 + $x; Dump($z); my $a = 10; Dump($a); print "\$a = $a\n"; Dump($a);

        This produces

        SV = PV(0x9c3c6d0) at 0x9c585c0 REFCNT = 1 FLAGS = (PADMY,POK,pPOK) PV = 0x9c53bc8 "10"\0 CUR = 2 LEN = 4 SV = PV(0x9c3c730) at 0x9c58620 REFCNT = 1 FLAGS = (PADMY,POK,pPOK) PV = 0x9c50250 "10"\0 CUR = 2 LEN = 4 SV = IV(0x9c585ac) at 0x9c585b0 REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 10 SV = IV(0x9c65674) at 0x9c65678 REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 10 $a = 10 SV = PVIV(0x9c3e6b8) at 0x9c65678 REFCNT = 1 FLAGS = (PADMY,IOK,POK,pIOK,pPOK) IV = 10 PV = 0x9c66cc8 "10"\0 CUR = 2 LEN = 4

        The macros (SvIOK etc.) check the FLAGS. See Devel::Peek and Perlguts for more on how this works.

        In summary, it's not Perl that fails to recognize the string contains a string representation of an integer, it's Win32::OLE and Excel.

      I know this thread is old .. but this helped me tons today! I've been stuck on this error. I tried that adding 0 to my $col variable and no more errors! Thanks!! 0+$col
      Really helped.. thanks!