A long list of shape data does not stay in position filling in a dropdown

Started by Visisthebest, May 04, 2024, 04:34:17 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Visisthebest

I am running in to a pretty important usability issue with the shape data editor (for the end user).

The list of data items for this application is a lot longer than the shape editor window, if the user fills in a dropdown later in the list it always shifts position to put the item filled in to the end of the visible list items.

This is very awkward however for users that have to fill in lots of values quickly, it makes filling in a long list very user-unfriendly.

When you fill in a long list, you want it to stay in position. Now, after filling in one dropdown value you have to scroll down after each dropdown. Even more annoyingly, because scrolling still has focus on the dropdown when you use the keyboard to scroll down you change the value you just entered.

Are there ways to avoid this, or to otherwise help users fill in lots of data (a lot of dropdowns in this case) with the shape data editor?

Ideally someone knows a solution, but a good workaround would be great too!
Visio 2021 Professional

wapperdude

...sitting in my rocking chair, those Visio issues won't leave me alone...

Long lists seem problematical no matter how you slice them.  Slice them???  Hmmmm.  Off the top of my head, no thinking involved, how about multiple shapes?  Each shape has a smaller portion of the main list.

Visio 2019 Pro

Visisthebest

Thank you Wapperdude yes that is one option, we can even make it so the shape data of one shape (a smaller list of data items) is pushed in to the main shape shape (that has the long list) each time a value is changed.

Hopefully there is another option to deal with this as well. A custom winform is another solution of course, or working via Excel import/export.
Visio 2021 Professional

Yacine

I am not sure if I understand. Can you upload an example?

Otherwise 2 ideas
1) cascading dropdowns that subdivides the range of entries into categories, possibly over multiple levels
2) write a custom form in winform or VBA
Yacine

Visisthebest

Yacine it is really easy to simulate, in Define Shape Data just keep pressing New and you'll have 30 or more data items in a few seconds.

Try to edit them in the data editor, the problem is also there when editing strings, and you'll see the position of the items in the shape data editor shift each time you press enter. This is the problem, makes it very hard to fill in long lists of data terrible UX this way.

I am considering making a generic WinForm solution for this issue.
Visio 2021 Professional

Yacine

I kinda understand that you let your users edit not only the value, but the whole definition of the prop section?
Usually users open the shape data window and edit only the values of the props.
Yacine

Visisthebest

No I mean users just editing the data not the definition of the shape data (in fact I disable shape data defining  in the end user file).

It's just very easy to see, quickly add say 30 string fields with the New button in define shape data, then when editing shape data you see the problem.
Visio 2021 Professional

wapperdude

From my rocking chair musing, it seems to me that Visio isn't the best tool for handling such large amount of data entries.  It's hard to envision a scenario where a single shape would need such a large amount of data availability. 

The closest I've come would be some high pin count semiconductor device. Perhaps a programmable device where pin functionality might change.  My strategy would be to construct the shape via code...which has been done, but needs embellishment.  The embellishment would be to add Shapedata to each pin.  The shapedata, at least initially, is defined in Excel, where it could be structured into some meaningful, efficient arrangement.  Perhaps, introduce SETATREF() to allow direct shape updating to back flush into the data?  But, then, if this were a PGA device, I wouldn't be using Visio at all.

Well, need to refresh my cup of coffee...
Visio 2019 Pro

Yacine

The subject inspired me. Have a look at the enclosed files.
They may give you some inspiration as well and maybe start a longer discussion.

The first demonstrates displaying only certain sub-sections of the props.
I has a global switch - ignore (shows what the sub-sections want), all on, all off
Each section has a title, highlighted by "___" title "___" to toggle the visibility of the subsection.
What I haven't done is realize a deeper hierarchy than 1. But probably easily doable.

The second approach is a form, but unlike standard forms, it is non-modal (stays open) and shows the values of the current selected shape.
With auto-update in both directions.
Splitable in sub-sections by means of a tab control.
This offers the biggest versatility, watch page 2 of the tab control, where it demonstrates the concatenation and spliting of values.
This probably a more tedious part. At least for me in VBA.
If you were to accept the idea to work with Python, then an automatically generated form is thinkable.
As for the code itself. Python may also help by generating the VBA, which you would then copy paste into the VBA IDE.
But you're still stuck with the GUI to build up manually.

Last but not least having "input" sub-shapes.
This can be specially interesting if you want to play with some graphics stuff - sliders, connections, etc.

Visio is a quite powerful tool. Most often it's us being the "bottle neck".
Visualising how a UI / a workflow has to be is IMHO the expert part of coding.
Yacine

Yacine

And the jupyter notebook for the preparation magic.

# Too Many Props


```python
import xlwings as xw
```


```python
run vBase.ipynb
```

    Microsoft Visio
    TooManyProps_2024_05_07.vsdm
    Zeichenblatt-1
   


```python
filename = r'C:\Users\...\Documents\Visguy\TooManyProps\Props.xlsm' # insert the right path here.
```


```python
wb = xw.Book(filename)
```


```python
sht = wb.sheets[0]
data = sht.range('Table1').value
```


```python
data
```




    [[1.0, 'Base', 'personalID', 0.0, None],
     [2.0, 'Base', 'ForeName', 0.0, None],
     [3.0, 'Base', 'SecondName', 0.0, None],
     [4.0, 'Base', 'SurName', 0.0, None],
     [5.0, 'Base', 'BirtdDate', 5.0, None],
...




```python
shp = vWin.Selection(1)
```


```python
cats = []
for i in data:
    cat = i[1]
    if not cat in cats:
        cats.append(cat)
cats
```




    ['Base',
     'Address',
     'Contact',
     'Work',
     'HRL',
     'FacilityManagement',
     'Family',
     'Health',
     'Allergenes',
     'Medications',
     'OnCall']



### Collapsible Sub-sections


```python
cat_name = '___' + 'AllProps' + '___'
shp.AddNamedRow(visSectionProp, cat_name, visTagDefault)
shp.Cells('prop.' + cat_name + '.label').Formula = chr(34) + cat_name + chr(34)
shp.Cells('prop.' + cat_name + '.type').Formula = 1
shp.Cells('prop.' + cat_name + '.format').Formula = chr(34) + "INDIVIDUAL;TRUE;FALSE" + chr(34)
for cat in cats:
    cat_name = '___' + cat + '___'
    shp.AddNamedRow(visSectionProp, cat_name, visTagDefault)
    shp.Cells('prop.' + cat_name + '.label').Formula = chr(34) + cat_name + chr(34)
    shp.Cells('prop.' + cat_name + '.type').Formula = 3
    if cat == 'Base':
        shp.Cells('prop.' + cat_name).Formula = "TRUE"
        shp.Cells('prop.' + cat_name + '.invisible' ).Formula = "TRUE"
    cat_rows = [i for i in data if i[1] == cat]
    for row in cat_rows:
        prop = row[2]
        type_ = int(row[3])
        shp.AddNamedRow(visSectionProp, prop, visTagDefault)
        shp.Cells('prop.' + prop + '.label').Formula = chr(34) + prop + chr(34)
        shp.Cells('prop.' + prop + '.type').Formula = type_
        if type_ == 1:
            format_ = row[4]
            if format_:
                shp.Cells('prop.' + prop + '.format' ).Formula = chr(34) + format_ + chr(34)
        if cat != "Base":
            formula = 'IF(STRSAME(Prop.___AllProps___,"INDIVIDUAL"),NOT(Prop.' + cat_name + '),NOT(Prop.___AllProps___) )'
            #print(formula)
            shp.Cells('prop.' + prop + '.invisible' ).FormulaU = formula
   
```


```python
shp.DeleteSection(visSectionProp)
```

### Input form


```python
for cat in cats:
    cat_name = '___' + cat + '___'
    '''shp.AddNamedRow(visSectionProp, cat_name, visTagDefault)
    shp.Cells('prop.' + cat_name + '.label').Formula = chr(34) + cat_name + chr(34)
    shp.Cells('prop.' + cat_name + '.type').Formula = 3
    if cat == 'Base':
        shp.Cells('prop.' + cat_name).Formula = "TRUE"
        shp.Cells('prop.' + cat_name + '.invisible' ).Formula = "TRUE"
    '''
    cat_rows = [i for i in data if i[1] == cat]
    for row in cat_rows:
        prop = row[2]
        type_ = int(row[3])
        shp.AddNamedRow(visSectionProp, prop, visTagDefault)
        shp.Cells('prop.' + prop + '.label').Formula = chr(34) + prop + chr(34)
        shp.Cells('prop.' + prop + '.type').Formula = type_
        if type_ == 1:
            format_ = row[4]
            if format_:
                shp.Cells('prop.' + prop + '.format' ).Formula = chr(34) + format_ + chr(34)
    '''
        if cat != "Base":
            formula = 'IF(STRSAME(Prop.___AllProps___,"INDIVIDUAL"),NOT(Prop.' + cat_name + '),NOT(Prop.___AllProps___) )'
            #print(formula)
            shp.Cells('prop.' + prop + '.invisible' ).FormulaU = formula
    '''
```

### Sub-shapes as input



```python
shp.ConvertToGroup()
```


    ---------------------------------------------------------------------------

    com_error                                 Traceback (most recent call last)

    Cell In[51], line 1
    ----> 1 shp.ConvertToGroup()
   

    File D:\miniconda3\envs\YG1\Lib\site-packages\win32com\gen_py\00021A98-0000-0000-C000-000000000046x0x4x16\IVShape.py:155, in IVShape.ConvertToGroup(self)
        154 def ConvertToGroup(self):
    --> 155     return self._oleobj_.InvokeTypes(48, LCID, 1, (24, 0), (),)
   

    com_error: (-2147352567, 'Ausnahmefehler aufgetreten.', (0, 'Visio Professional', '\n\nRequested operation is presently disabled.', None, 0, -2032465766), None)



```python
previous_shp = None
for row in data:
    field = row[2]
    #print(field)
    fieldshp = shp.Drop(vDoc.Masters("Field"),1,1)
    try:
        fieldshp.NameU = field
    except:
        print("Error with :", field)
    fieldshp.Cells('user.invisible').Formula = "not(sheet." + str(shp.ID) + "!user.editmode)"
    if previous_shp:
        fieldshp.Cells('pinx').Formula = "sheet." + str(previous_shp.ID) + "!pinx"
        formula = "if(sheet." + str(shp.ID) + "!user.editmode; sheet." + str(previous_shp.ID) + "!piny - sheet." + str(previous_shp.ID) + "!height;0)"
        print(formula)
        fieldshp.Cells('piny').Formula = formula
    else:
        fieldshp.Cells('pinx').Formula = "sheet." + str(shp.ID) + "!controls.input"
        fieldshp.Cells('piny').Formula = "sheet." + str(shp.ID) + "!controls.input.y"
    previous_shp = fieldshp
previous_shp = None
```

    if(sheet.1!user.editmode; sheet.374!piny - sheet.374!height;0)
    if(sheet.1!user.editmode; sheet.376!piny - sheet.376!height;0)
...
   


```python
n = shp.Shapes.Count
for i in range(n,0,-1):
    shp.Shapes(i).Delete()
```


```python

```

Yacine