block-level on error undo, throw.
using System.IO.Compression.CompressionLevel from assembly.
using System.IO.Compression.ZipArchive from assembly.
using System.IO.Compression.ZipArchiveEntry from assembly.
using System.IO.Compression.ZipArchiveMode from assembly.
using System.IO.FileAccess from assembly.
using System.IO.FileMode from assembly.
using System.IO.FileShare from assembly.
using System.IO.FileStream from assembly.
using System.IO.Path from assembly.
using System.IO.Stream from assembly.
define temp-table ttSourceFile
    field fullpathname as character
    field filename     as character.
/* ********************  Preprocessor Definitions  ******************** */
/* ************************  Function Prototypes ********************** */
function IsFileLocked returns logical private
    (input filename as character) forward.
/* ***************************  Main Block  *************************** */
define variable sourceFolderPath as character no-undo.
define variable zipFile          as character no-undo.
define variable filename         as character no-undo.
define variable files            as class     "System.String[]" no-undo.
assign
    sourceFolderPath = session:temp-directory
    zipFile          = sourceFolderPath + substitute('\&1.zip', iso-date(today)) .
files = System.IO.Directory:GetFiles(sourceFolderPath).
define variable indexpos as integer no-undo.
do indexpos = 1 to files:length:
    filename = files:GetValue(indexpos - 1).
  
    //Exclude all zip files.
    if filename matches "*.zip" then
        next.
      
    file-info:file-name = filename.
  
    if file-info:file-create-date lt today then
    do:
      
        if IsFileLocked(input file-info:full-pathname) then
            next.
      
        create ttSourceFile.
      
        assign
            ttSourceFile.filename     = Path:GetFileName(file-info:full-pathname) //
            ttSourceFile.fullpathname = file-info:full-pathname.
      
    end.   
end.
run CreateZIPFile(input zipFile).
file-info:file-name = zipFile.
message file-info:full-pathname
    view-as alert-box info.
return.
finally:
  
    empty temp-table ttSourceFile.
  
end finally.
/* **********************  Internal Procedures  *********************** */
procedure CreateZIPFile private:
    /*------------------------------------------------------------------------------
     Purpose:
     Notes:
    ------------------------------------------------------------------------------*/
    define variable fileEntry        as class ZipArchiveEntry no-undo.
    define variable fileEntryStream  as class Stream          no-undo.
    define variable sourceFileStream as class FileStream      no-undo.
    define variable zipFileStream    as class FileStream      no-undo.
    define variable archive          as class ZipArchive      no-undo.
  
    define input parameter zipFile as character no-undo.
  
    zipFileStream  = new FileStream(zipFile, FileMode:Create).
    archive = new ZipArchive(zipFileStream, ZipArchiveMode:Create).
    for each ttSourceFile:
      
        fileEntry = archive:CreateEntry(ttSourceFile.filename, CompressionLevel:Fastest). 
        fileEntryStream = fileEntry:Open().
  
        sourceFileStream  = System.IO.File:OpenRead(ttSourceFile.fullpathname).
      
        if sourceFileStream:CanRead then
        do:
            sourceFileStream:CopyTo(fileEntryStream).
            sourceFileStream:Close().
          
        end.
      
        //Closes the current stream and releases any resources associated with the current stream.
        fileEntryStream:Close().
      
      
    end.
  
    catch e1 as Progress.Lang.Error :
              
        message e1:GetMessage(1)
            view-as alert-box error.
              
    end catch. 
  
    finally:
      
//Clears buffers for this stream and causes any buffered data to be written to the file.
        zipFileStream:Flush().
// This method finishes writing the archive and releases all resources used by the ZipArchive object.
        archive:Dispose(). //Releases all resources used by the ZipArchive object.
  
    end finally.
  
  
end procedure.
/* ************************  Function Implementations ***************** */
function IsFileLocked returns logical private
    ( input sourceFile as character ):
    /*------------------------------------------------------------------------------
     Purpose: TEst to see if a file is locked by another process
     Notes:
    ------------------------------------------------------------------------------*/ 
    define variable fs as class FileStream no-undo.
      
    fs = System.IO.File:Open(sourceFile, FileMode:Open, FileAccess:Read, FileShare:None).
  
    return false.
  
    catch IOe as System.IO.IOException:
      
        //message IOe:message.
      
        return true.
    end catch.
  
    catch e1 as Progress.Lang.Error :
        return true.
    end catch.
  
    finally:
      
        if valid-object(fs) then
        do:
            fs:Close().
            delete object fs.
        end.   
    end finally.
      
end function.