Samples‎ > ‎NativePeer‎ > ‎

Find Writable Subranges in a Protected Range

This sample demonstrates how to find writable subranges in a range that contains protected cells.


import com.jniwrapper.Int32;
import com.jniwrapper.win32.automation.OleMessageLoop;
import com.jniwrapper.win32.automation.types.VarType;
import com.jniwrapper.win32.automation.types.Variant;
import com.jniwrapper.win32.excel.*;
import com.jniwrapper.win32.excel.CellFormat;
import com.jniwrapper.win32.excel.XlReferenceStyle;
import com.jniwrapper.win32.excel.XlSearchDirection;
import com.jniwrapper.win32.excel._Application;
import com.jniwrapper.win32.jexcel.Application;
import com.jniwrapper.win32.jexcel.Range;
import com.jniwrapper.win32.jexcel.Workbook;
import com.jniwrapper.win32.jexcel.Worksheet;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.List;

public class FindWritableSubrangesSample {
    public static void main(String[] args) {
        Application application = null;
        Workbook workbook = null;
        try{
            application = new Application();
            workbook = application.openWorkbook(new File("protected.xls"));
            Worksheet worksheet = workbook.getWorksheet(1);
            Range range = worksheet.getRange("A1:F11");
            List<String> writableSubranges = findWritableSubranges(range);
            for (String s : writableSubranges) {
                System.out.println("s = " + s);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (workbook != null) {
                workbook.close(false);
            }
            if (application != null) {
                application.close(true);
            }
        }
    }

    public static List<String> findWritableSubranges(final Range range) throws InvocationTargetException, InterruptedException {
        final OleMessageLoop messageLoop = range.getOleMessageLoop();
        final List<String> result = new LinkedList<String>();
        final com.jniwrapper.win32.excel.Range peer = range.getPeer();

        messageLoop.doInvokeAndWait(new Runnable() {
            public void run() {
                if (!isRangeLocked(peer)) {
                    result.add(getRangeAddress(peer));
                    return;
                }
                _Application application = peer.getApplication();
                Variant findLockedCells = getFindLockedCells(application);
                setFindLockedCells(application, new Variant(false));

                performSearch(peer, result);

                setFindLockedCells(application, findLockedCells);

                application.setAutoDelete(false);
                application.release();
            }
        });
        return result;
    }

    private static void performSearch(com.jniwrapper.win32.excel.Range peer, List<String> result) {
        List<com.jniwrapper.win32.excel.Range> allocatedRanges = new LinkedList<com.jniwrapper.win32.excel.Range>();
        Variant empty = Variant.createUnspecifiedParameter();

        com.jniwrapper.win32.excel.Range found = findInRange(peer, empty);
        com.jniwrapper.win32.excel.Range results = found;
        if(!found.isNull()) {
            String firstAddress = getRangeAddress(found);
            boolean wrappedAround = false;

            while (!wrappedAround) {
                allocatedRanges.add(found);
                allocatedRanges.add(results);

                results = getRangeUnion(results, found);
                found = findInRange(peer, new Variant(found));
                String address = getRangeAddress(found);
                if(firstAddress.equals(address)){
                    wrappedAround = true;
                    allocatedRanges.add(found);
                }
            }
        }
        com.jniwrapper.win32.excel.Areas areas = results.getAreas();
        long areasCount = areas.getCount().getValue();
        for (int i = 0; i < areasCount; i++) {
            com.jniwrapper.win32.excel.Range item = areas.getItem(new Int32(i + 1));
            result.add(getRangeAddress(item));
            allocatedRanges.add(item);
        }
        allocatedRanges.add(results);

        for (com.jniwrapper.win32.excel.Range item : allocatedRanges) {
            item.setAutoDelete(false);
            item.release();
        }
    }

    private static void setFindLockedCells(final _Application application, final Variant value){
        CellFormat findFormat = application.getFindFormat();
        findFormat.setLocked(value);

        findFormat.setAutoDelete(false);
        findFormat.release();
    }

    private static Variant getFindLockedCells(final _Application application){
        CellFormat findFormat = application.getFindFormat();
        Variant locked = findFormat.getLocked();

        findFormat.setAutoDelete(false);
        findFormat.release();
        return locked;
    }

    private static String getRangeAddress(com.jniwrapper.win32.excel.Range range) {
        Variant vFalse = new Variant(false);
        Variant vTrue = new Variant(true);
        return range.getAddress(vFalse,
                vFalse,
                new XlReferenceStyle(XlReferenceStyle.xlA1),
                vTrue,
                Variant.createUnspecifiedParameter()).getValue();
    }

    private static boolean isRangeLocked(com.jniwrapper.win32.excel.Range range){
        Variant locked = range.getLocked();
        boolean result = locked.getVt().getValue() == VarType.VT_NULL;
        if(!result){
            result = locked.getBoolVal().getBooleanValue();
        }
        return result;
    }

    private static com.jniwrapper.win32.excel.Range getRangeUnion(com.jniwrapper.win32.excel.Range range1, com.jniwrapper.win32.excel.Range range2) {
        _Application application = range1.getApplication();
        Variant empty = Variant.createUnspecifiedParameter();
        com.jniwrapper.win32.excel.Range result = application.union(range1,
                range2,
                empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
                empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
                empty, empty, empty, empty, empty, empty, empty, empty, new Int32(0));
        application.setAutoDelete(false);
        application.release();
        return result;
    }

    private static com.jniwrapper.win32.excel.Range findInRange(com.jniwrapper.win32.excel.Range range, Variant after) {
        Variant empty = Variant.createUnspecifiedParameter();
        return range.find(
                new Variant(""),
                after,
                empty,
                empty,
                empty,
                new XlSearchDirection(XlSearchDirection.xlNext),
                empty,
                empty,
                new Variant(true)
        );
    }
}