slick.user has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm trying to use Conditional Formatting. I recorded the Macro (comment inside code) and tried to translate to Perl OLE with the code below but got error: Can't call method "Font" on an undefined value at excel_test.pl line 56. I can loop through each cell and check if it not equal to "TRUE" and assign color. I'm trying to avoid looping in Perl.
use strict; use warnings; use Win32::OLE; use Win32::OLE qw(in with); my $EXCEL = Win32::OLE->new("Excel.Application","Quit"); $EXCEL->{"Visible"} = 1; $EXCEL->{DisplayAlerts}= 0; my $outfile = "C:\\test\\file1.xls"; $EXCEL -> {"SheetsInNewWorkBook"} = 1; my $Workbook = $EXCEL -> Workbooks -> Add(); my $CurrentSheet = $Workbook -> Worksheets(1); $CurrentSheet->Range("A1")->{"Value"} = "DataA"; $CurrentSheet->Range("A2")->{"Value"} = "abs"; $CurrentSheet->Range("A3")->{"Value"} = "FALSE"; $CurrentSheet->Range("A4")->{"Value"} = "TRUE"; $CurrentSheet->Range("A5")->{"Value"} = "ABC"; $CurrentSheet->Range("A6")->{"Value"} = "xyz"; $CurrentSheet->Range("A7")->{"Value"} = "123"; $CurrentSheet->Range("A8")->{"Value"} = "-99999"; $CurrentSheet->Range("A9")->{"Value"} = "TRUE"; $CurrentSheet->Range("A10")->{"Value"} = "10"; $CurrentSheet->Range("B1")->{"Value"} = "DataB"; $CurrentSheet->Range("B2")->{"Value"} = "absx"; $CurrentSheet->Range("B3")->{"Value"} = "FALSE"; $CurrentSheet->Range("B4")->{"Value"} = "TRUE"; $CurrentSheet->Range("B5")->{"Value"} = "ABCx"; $CurrentSheet->Range("B6")->{"Value"} = "xyzx"; $CurrentSheet->Range("B7")->{"Value"} = "123x"; $CurrentSheet->Range("B8")->{"Value"} = "-99999x"; $CurrentSheet->Range("B9")->{"Value"} = "TRUE"; $CurrentSheet->Range("B10")->{"Value"} = "10x"; $CurrentSheet->Range("C1")->{"Value"} = "A=B?"; #my $rangeFormat = $CurrentSheet->Range("A4"); #$rangeFormat->Interior->{Color} = 255; # Columns("A:A").Select # Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlNot +Equal, _ # Formula1:="=TRUE" # Selection.FormatConditions(Selection.FormatConditions.Count).SetF +irstPriority # With Selection.FormatConditions(1).Font # .Color = -16776961 # .TintAndShade = 0 # End With # Selection.FormatConditions(1).StopIfTrue = True my $rangeFormat = $CurrentSheet->Range("A:A"); $rangeFormat->FormatConditions->Add({Type=>"xlCellValue", Operator=>"x +lNotEqual", Formula1=>"=TRUE"}); $rangeFormat->FormatConditions(1)->Font->{Color} = -16776961; $Workbook->SaveAs({FileName => $outfile, FileFormat => -4143}); $Workbook -> Save(); $EXCEL->Quit(); Win32::OLE->FreeUnusedLibraries();

Replies are listed 'Best First'.
Re: Win32::OLE Excel Conditional Formatting error
by pryrt (Abbot) on Feb 29, 2024 at 20:23 UTC
    The VBA macro shows Type:=xlCellValue ; in your perl code, you instead have Type => "xlCellValue". The string "xlCellValue" is not the same as the constant xlCellValue

    To gain access to the xl* family of constants, Win32::OLE::Const allows you to

    use Win32::OLE::Const 'Microsoft Excel';

    To use those constants in your call, you need to run

    $rangeFormat->FormatConditions->Add({Type=>xlCellValue, Operator=>xlNo +tEqual, Formula1=>"=TRUE"})

    When I made those two changes to your code, I was able to see conditional formatting in the spreadsheet your code created.

      Thanks. I used Danny's solution. Win32::OLE::Const 'Microsoft Excel'; has to be on Win32 Excel only. I'm using Win64 Excel version.
Re: Win32::OLE Excel Conditional Formatting error
by Danny (Chaplain) on Feb 29, 2024 at 17:15 UTC
    That means, for whatever reason, $rangeFormat->FormatConditions(1) is not defined at line 56.
Re: Win32::OLE Excel Conditional Formatting error
by Danny (Chaplain) on Feb 29, 2024 at 18:54 UTC
    I just installed Win32::OLE and changed line 56 to
    $rangeFormat->Font->{Color} = -16776961;
    and it made the font in the first column red, if that is what you were trying to do.
      A4 & A9 should not be red because of Conditional Formatting. It is not apply right now. I was trying to follow macro code.
        It looks like you need to use numeric values for Type and Operator in FormatConditions->Add. For example
        $rangeFormat->FormatConditions->Add({Type=>1, Operator=>4, Formula1=>" +=TRUE"}); $rangeFormat->FormatConditions(1)->Font->{Color} = -16776961;
        makes cells in the first column red except A4 and A9. Here are the codes for Type and Operator.
      I was trying to use Conditional Formatting, if it is not "TRUE" to highlight all red.
Re: Win32::OLE Excel Conditional Formatting error
by InfiniteSilence (Curate) on Mar 02, 2024 at 17:38 UTC

    When I used to use Windows regularly and I saw that you could write stuff with less code I never looked back...(this is just a style comment btw)

    #!/usr/bin/perl -w use strict; my @data = qw~DataB absx FALSE TRUE ABCx xzx 123x .99999x TRUE 10x~; for(0..$#data){ my $n= $_+1; print qq~\$CurrentSheet->Range("A$n")->{"Value"} = "$data[$_]"\n~; } 1;

    Celebrate Intellectual Diversity