ตรวจสอบว่าป๊อปอัปอยู่เบื้องหน้าของ Excel หรือไม่

ฉันกำลังเขียน VSTO Add-in สำหรับ Excel และฉันสังเกตเห็นว่าถ้าฉันล็อคแผ่นงานและรหัสผ่านป้องกันมัน (ดังนั้นเฉพาะ Add-in ของฉันเท่านั้นที่สามารถเขียนลงไปได้ แต่ผู้ใช้สามารถดูได้) หากผู้ใช้พยายามแก้ไข แผ่นงานที่พวกเขาได้รับป๊อปอัป "แผ่นงานนี้ถูกล็อค" หากในขณะที่พร้อมท์นั้นยังคงรอการป้อนข้อมูลของผู้ใช้ Add-in จะพยายามเขียนลงในแผ่นงาน Excel จะหยุดทำงาน การเขียนลงในชีตเกี่ยวข้องกับการยกเลิกการปกป้อง การเขียนข้อมูล แล้วล็อคอีกครั้ง Add-in จะจับข้อมูลจากแหล่งภายนอกผ่านพอร์ตอนุกรม เพื่อให้สามารถเขียนข้อมูลได้ตลอดเวลา

วิธีสร้างใหม่: 1. ล็อคแผ่นด้วย Add-in 2. ผู้ใช้พยายามแก้ไขเนื้อหาชีต 3. ผู้ใช้ได้รับแจ้งว่าไม่สามารถแก้ไขเนื้อหาของชีตได้เนื่องจากถูกล็อค 4. ข้อมูลเข้ามาในพอร์ตอนุกรมและ Add-in จะพยายามปลดล็อก เขียนข้อมูล และล็อกแผ่นงานก่อนที่ผู้ใช้จะมีโอกาสตอบรับพร้อมท์ที่ถูกส่งออกไป 5. Excel ไบต์ฝุ่น

มีข้อเสนอแนะอะไรบ้าง? ฉันกำลังเล่นกับแนวคิดในการรักษาแผ่นงาน "ต้นแบบ" ที่ซ่อนอยู่และแผ่นงานที่มองเห็นได้ และเพียงใช้สูตร Excel หรือช่วงที่มีชื่อเพื่ออ้างอิงแผ่นงานที่ซ่อนอยู่ อย่างไรก็ตาม สิ่งนี้จะเปิดกว้างสำหรับการแก้ไขและข้อมูลที่อาจเกิดความเสียหายโดยผู้ใช้ ข้อมูลจะต้องไม่สามารถแก้ไขได้มากที่สุด

อัปเดต: ฉันจะพอใจกับการจับ COMException ดังนั้นมันจึงไม่ฆ่า Excel แต่ดูเหมือนว่า "catch (Exception ex)" ทั่วไปจะไม่ช่วยอะไร


person Pete Garafano    schedule 28.12.2011    source แหล่งที่มา


คำตอบ (4)


ใน VBA คุณสามารถป้องกันแผ่นงานด้วย UserInterFaceOnly:=True ซึ่งหมายความว่าโค้ดยังสามารถเขียนลงในแผ่นงานได้ จากลิงก์นี้ ดูเหมือนว่าสิ่งนี้จะเกิดขึ้นกับ VSTO addin เช่นกัน

person Doug Glancy    schedule 29.12.2011
comment
ฉันได้ตั้งค่า UserInterFaceOnly = true ไว้แล้ว แต่ถ้าผู้ใช้ยังคงพยายามแก้ไขแบบฟอร์มในทางใดทางหนึ่ง มันจะเกิดกล่องข้อผิดพลาดที่ผู้ใช้ต้องคลิกตกลงก่อนที่โค้ดของฉันจะสามารถดำเนินการต่อไปได้โดยไม่ต้องส่ง COMException - person Pete Garafano; 29.12.2011

คุณอาจต้องตรวจสอบเพื่อให้แน่ใจว่าชีตอยู่ในโหมดโต้ตอบหรือเซลล์ที่ใช้งานอยู่ไม่เป็นโมฆะ หากการตรวจสอบล้มเหลว ออกจากฟังก์ชันที่ดำเนินการเขียน

 private bool IsExcelInteractive()
    {
        try
        {
            Globals.ThisAddIn.Application.Interactive = Globals.ThisAddIn.Application.Interactive;
            return true;
        }
        catch
        {
            return false;
        }
    }
person Brijesh Mishra    schedule 29.12.2011

เห็นได้ชัดว่าปัญหาเกิดขึ้น

catch(Exception)

ไม่ทำงานเหมือนกับ catch all ทั่วไปเมื่อพูดถึง COMException การเพิ่มบรรทัด

using System.Runtime.InteropServices;

แล้วเพิ่ม

catch(COMException)

ฉันพยายาม...จับบล็อกช่วยให้ฉันจัดการกับข้อผิดพลาดได้ดีขึ้น ผสมกับโค้ดบางส่วนเพื่อลองดำเนินการที่ล้มเหลวอีกครั้งสองสามครั้งหลังจากใช้งาน

SendKeys.SendWait("{ESC}");

ดูเหมือนจะทำให้สิ่งต่างๆ ดีขึ้น อย่างไรก็ตาม การส่งคีย์ Escape ไปยังโปรแกรมแถวหน้าแบบสุ่มสี่สุ่มห้าอาจทำให้เกิดปัญหาบางอย่างได้ แต่ฉันไม่สามารถนั่งวนซ้ำไม่รู้จบเพื่อรอผู้ใช้ที่อาจหรืออาจจะไม่ใส่ใจเพื่อแก้ไขปัญหาบนหน้าจอ ดูเหมือนว่าจะทำให้พอร์ตอนุกรมหยุดการบัฟเฟอร์ข้อมูลและปล่อยทิ้งไว้หากไม่ได้รับการจัดการเร็วพอ

person Pete Garafano    schedule 29.12.2011

แทนที่จะดำเนินการนี้เมื่อคลิกเซลล์ คุณสามารถเพิ่มปุ่มใน Ribbon และเมื่อคลิกแล้วให้ทำสิ่งนี้ วิธีนี้จะกำจัดหน้าต่างป๊อปอัป

person Brijesh Mishra    schedule 30.12.2011
comment
ปัญหาคือฉันกำลังทำงานอยู่เบื้องหลังโดยที่ผู้ใช้ไม่ต้องดำเนินการใดๆ กำลังประมวลผลข้อมูลที่เข้ามาในพอร์ตอนุกรม ข้อมูลไม่ได้ถูกกำหนดเวลาไว้ ดังนั้นหากผู้ใช้โต้ตอบกับ Excel เช่น มีเซลล์ที่เปิดอยู่เพื่อแก้ไข (หรือกำลังพยายามทำ แต่ทำไม่ได้เนื่องจากฉันล็อคเซลล์ไว้) และ Add-in VSTO พยายามโต้ตอบกับ Excel ส่วน Add-in ล้มเหลวในความโปรดปรานของผู้ใช้ ดูคำตอบของฉันสำหรับเคล็ดลับที่ฉันคิดขึ้นมาเพื่อแก้ไขปัญหานี้ - person Pete Garafano; 04.01.2012