PDA

View Full Version : Visibility of a table based on a checkbox value - Help?



Galahadoc
11-10-2008, 05:58 PM
Hi guys,

I found this (had hyperlink to the code but apparently with under 5 posts that is a no-no so i'll post it at the bottom of this post) code by Fumei which uses a checkbox (or other objects) to hide and un-hide tables (or text, or, from what i can gather, anything you want). After looking around for ages for something that will do what i wanted, finally thinking word just didn't have the functionality to do what was needed, i stumbled across this site.

Anyway, the problem i have run into is the way the checkboxes are working. I have 4 tables with a checkbox following the title which sits above each of the tables. So by default i would like the boxes to be unchecked and the table invisible, then when you check the box then the table appears, i've worked out this much through trial and error. But for some reason using the 2nd, 3rd, and 4th boxes effect all 4 tables in 1 way or another. I believe it's mainly effecting them when you check the box to open the table, it opens all of the tables, they then all collapse when you un-check that box.

Keeping in mind this is the first time i have actually knowingly used VBA, i somewhat understand the absolute basics only through knowing the absolute basics of other coding languages.

I was going to simply PM Fumei but given the knowledge of most people here i was hoping that maybe someone else could help aswell.

For the purpose of this document i use Word 2003; i have Word 2007 at my other house, is this going to effect the way this document works? (more curiosity then anything else).. I attached the document for reference and the code i have used is as follows:

Code from my document:
Option Explicit

Sub CheckBox1_Change()
Call ShowHideTable
End Sub

Sub ShowHideTable()
With Selection
.GoTo What:=wdGoToTable, Which:=wdGoToNext, _
Count:=1, Name:=""
.Tables(1).Select
End With
If CheckBox1.Value = False Then
With Selection.Font
.Hidden = True
End With
With ActiveWindow.View
.ShowHiddenText = False
.ShowAll = False
End With
Else
With Selection.Font
.Hidden = False
End With
With ActiveWindow.View
.ShowHiddenText = True
.ShowAll = False
End With
With Selection
.Collapse direction:=wdCollapseStart
.MoveLeft unit:=wdCharacter, Count:=1
End With
End If
End Sub


Private Sub CheckBox2_Change()
Call ShowHideTable2
End Sub

Sub ShowHideTable2()
With Selection
.GoTo What:=wdGoToTable, Which:=wdGoToNext, _
Count:=1, Name:=""
.Tables(1).Select
End With
If CheckBox2.Value = False Then
With Selection.Font
.Hidden = True
End With
With ActiveWindow.View
.ShowHiddenText = False
.ShowAll = False
End With
Else
With Selection.Font
.Hidden = False
End With
With ActiveWindow.View
.ShowHiddenText = True
.ShowAll = False
End With
With Selection
.Collapse direction:=wdCollapseStart
.MoveLeft unit:=wdCharacter, Count:=1
End With
End If
End Sub

Sub CheckBox3_Click()
Call ShowHideTable3
End Sub

Sub ShowHideTable3()
With Selection
.GoTo What:=wdGoToTable, Which:=wdGoToNext, _
Count:=1, Name:=""
.Tables(1).Select
End With
If CheckBox3.Value = False Then
With Selection.Font
.Hidden = True
End With
With ActiveWindow.View
.ShowHiddenText = False
.ShowAll = False
End With
Else
With Selection.Font
.Hidden = False
End With
With ActiveWindow.View
.ShowHiddenText = True
.ShowAll = False
End With
With Selection
.Collapse direction:=wdCollapseStart
.MoveLeft unit:=wdCharacter, Count:=1
End With
End If
End Sub

Sub CheckBox4_Click()
Call ShowHideTable4
End Sub

Sub ShowHideTable4()
With Selection
.GoTo What:=wdGoToTable, Which:=wdGoToNext, _
Count:=1, Name:=""
.Tables(1).Select
End With
If CheckBox4.Value = False Then
With Selection.Font
.Hidden = True
End With
With ActiveWindow.View
.ShowHiddenText = False
.ShowAll = False
End With
Else
With Selection.Font
.Hidden = False
End With
With ActiveWindow.View
.ShowHiddenText = True
.ShowAll = False
End With
With Selection
.Collapse direction:=wdCollapseStart
.MoveLeft unit:=wdCharacter, Count:=1
End With
End If
End Sub



Code from Fumei:

Option Explicit

Sub CheckBox1_Change()
Call ShowHideTable
End Sub

Sub ShowHideTable()
With Selection
.GoTo What:=wdGoToTable, Which:=wdGoToNext, _
Count:=1, Name:=""
.Tables(1).Select
End With
If CheckBox1.Value = True Then
With Selection.Font
.Hidden = True
End With
With ActiveWindow.View
.ShowHiddenText = False
.ShowAll = False
End With
Else
With Selection.Font
.Hidden = False
End With
With ActiveWindow.View
.ShowHiddenText = True
.ShowAll = True
End With
With Selection
.Collapse direction:=wdCollapseStart
.MoveLeft unit:=wdCharacter, Count:=1
End With
End If
End Sub


' the other View properties
' if you want to still see paragraph marks, you
' must explicitly turn it on = True
' .ShowAnimation = True
' .Draft = False
' .WrapToWindow = False
' .ShowPicturePlaceHolders = False
' .ShowFieldCodes = False
' .ShowBookmarks = False
' .FieldShading = wdFieldShadingWhenSelected
' .ShowTabs = False
' .ShowSpaces = False
' .ShowParagraphs = False
' .ShowHyphens = False
' .ShowHiddenText = False
' .ShowAll = True
' .ShowDrawings = True
' .ShowObjectAnchors = False
' .ShowTextBoundaries = False
' .ShowHighlight = True
' .DisplayPageBoundaries = True
' .DisplaySmartTags = True

' this is to do the same thing with a bookmark ("mytext")
' using a second checkbox (Checkbox2)

Sub CheckBox2_Change()
Call ShowHideBookmark
End Sub


Sub ShowHideBookmark()
Dim orange As Range
Set orange = ActiveDocument.Bookmarks("mytext").Range
If CheckBox2.Value = True Then
With orange.Font
.Hidden = True
End With
With ActiveWindow.View
.ShowHiddenText = False
.ShowAll = False
End With
Else
With orange.Font
.Hidden = False
End With
With ActiveWindow.View
.ShowHiddenText = True
.ShowAll = True
End With
End If
End Sub


Thanks guys, hope you can help.

lucas
11-10-2008, 10:02 PM
I just commented the code that was operating on the active window in each module: see attached.


I'm not sure how this will work in 07. I don't see any immediate problem but I don't have 2007 to test with.

I think Gerry would suggest bookmarking the tables and using the bookmark reference rather than the table index.

lucas
11-10-2008, 10:20 PM
To use bookmarks, select the first table and go to insert bookmark....name it Table1

Replace this section in the ShowHideTable module:

With Selection
.GoTo What:=wdGoToTable, Which:=wdGoToNext, _
Count:=1, Name:=""
.Tables(1).Select
End With


with this:

ActiveDocument.Bookmarks("Table1").Select


Do the same for each table, incrimenting each table number in the bookmark and in the code.......

Galahadoc
11-10-2008, 11:38 PM
That's terrific Lucas, thanks heaps for the help! I had a look and can see that there is now code that has been commented, are you able to give a brief explanation as to why that made a difference? If you can't explain it simple like then don't worry, i'm just happy it's working..

Haven't got time to play around with it anymore right now but once i get home, hopefully it runs fine in Word07, i'll run it bookmarked. Just to clarify this is more to just clean up the code then anything else?
Theoretically, if the tables were bookmarked, could i make them appear with checkboxes at the top of the page rather then with a checkbox right above the table? I'm thinking this is what the second part of Fumei's code was for?..

{ G }

lucas
11-10-2008, 11:48 PM
G, this part in each module:

With ActiveWindow.View
.ShowHiddenText = False
.ShowAll = False
End With



I think was acting on more than the table you wanted it to work on.....the activewindow is the key word in my humble estimation.

As far as where the checkboxes are located......I don't see that it should make any difference where they are located on the document, whether bookmarked or not it should still work I believe.

Word isn't really my gig so maybe Gerry or Malcolm or one of the other Word regulars will come along and clear it up better for both of us.

Galahadoc
11-11-2008, 08:26 PM
Thanks Lucas, very much appreciated.

I need to add "Filling in forms" protection to the document, but when i do clicking the checkboxes causes an error, i assume this is because the code doesn't have permission? I thought i seen a similar issue while browsing through this forum yesterday and there was a code to input which will allow the code to work regardless of what protection is on.. I can't actually find the thread again now, do you, or anyone else, know it?

Would this solve my issue anyway?

{ G }

fumei
11-12-2008, 01:15 PM
"I think Gerry would suggest bookmarking the tables and using the bookmark reference rather than the table index."

Indeed....I would.

Document redone and attached as Gerry_Yadda.doc

What it does.

The key code is:
Sub MyShowHideTable(bolIn As Boolean, strTable As String)
Dim aTable As Table
Set aTable = ActiveDocument.Bookmarks(strTable) _
.Range.Tables(1)

aTable.Range.Font.Hidden = Not bolIn
Set aTable = Nothing
End Sub

This procedure takes two parameters, a Public variable bolIn (Boolean, so it is either True or False), and a string strTable.

Each table has been bookmarked: CB1, CB2, CB3, CB4. That name is passed to MyShowHideTable, along with True/False determined by the value of a checkbox. Let's see an example, say Checkbox1.

Option Explicit

Sub CheckBox1_Change()
If CheckBox1.Value = True Then
Call MyShowHideTable(True, "CB1")
Else
Call MyShowHideTable(False, "CB1")
End If
End Sub

If Checkbox1 is checked, bolIn = True.
The value of strTable is set as "CB1".

These are passed to MyShowHideTable. In this case (it IS checked),

Sub MyShowHideTable(bolIn As Boolean, strTable As String)
...the code
becomes:


Sub MyShowHideTable(True, "CB1")
' make a table object from the bookmark
' using the name passed as parameter
Dim aTable As Table
Set aTable = ActiveDocument.Bookmarks("CB1") _
.Range.Tables(1)

' reverse the Boolean value using = Not
' if TRUE (checked), then Hidden should be FALSE
' if FALSE (unchecked), then Hidden should be TRUE

aTable.Range.Font.Hidden = Not bolIn
Set aTable = Nothing
End Sub


Done. here is the FULL code for the entire process.
Option Explicit

Sub CheckBox1_Change()
If CheckBox1.Value = True Then
Call MyShowHideTable(True, "CB1")
Else
Call MyShowHideTable(False, "CB1")
End If
End Sub
Sub CheckBox2_Change()
If CheckBox2.Value = True Then
Call MyShowHideTable(True, "CB2")
Else
Call MyShowHideTable(False, "CB2")
End If
End Sub
Sub CheckBox3_Change()
If CheckBox3.Value = True Then
Call MyShowHideTable(True, "CB3")
Else
Call MyShowHideTable(False, "CB3")
End If
End Sub
Sub CheckBox4_Change()
If CheckBox4.Value = True Then
Call MyShowHideTable(True, "CB4")
Else
Call MyShowHideTable(False, "CB4")
End If
End Sub


Sub MyShowHideTable(bolIn As Boolean, strTable As String)
Dim aTable As Table
Set aTable = ActiveDocument.Bookmarks(strTable) _
.Range.Tables(1)

aTable.Range.Font.Hidden = Not bolIn
Set aTable = Nothing
End Sub


Note that Selection is never used at all.


As a final comment, I have to strongly, strongly recommend that:

1. you use Styles.
2. give explicit names to objects. Many many of the formfields have NO names (and therefore no bookmarks)

Further, I had to write code to even find the Checkboxes in the document.

If you even intend to get data/information out via code, not having explicit names will be a big, big, problem.

Galahadoc
11-12-2008, 04:18 PM
Awesome Gerry! An i kinda understood what you were saying aswell..

So i should be able to have the checkboxes anywhere now because it's not using the code to simply hide the 'next' table, but instead a specific, now named, table?..

As far as styles, and naming check boxes, etc.. I've adopted the form from someone else who flogged it from someone in the IS dept. I've only made changes and improvements.. Although, in saying that, i wasn't really aware of the existence of this VBA stuff prior to a few days ago, i've always figured if the document looks fine printed on a piece of paper everyone is happy..... (I'll change my dirty filthy ways now that i understand there is a whole other world to word)..

Thank you soo much for the help guys, this forum is full of some really fantastic people.

{ G }

fumei
11-13-2008, 01:15 PM
"So i should be able to have the checkboxes anywhere now because it's not using the code to simply hide the 'next' table, but instead a specific, now named, table?.."

Correct!

Using "next" for something can work obviously, but also obviously it has a severe limitation. The next whatever does, in fact, have to BE next.

This way, the relationship is between object and object. The Checkbox and a specific table. Once that relationship is properly established, it does not matter where they are in the document. The table can be moved anywhere...the bookmark will automatically adjust.

Be careful though. While yes you can use a "name" to create a table object of a specific table, the table itself is NOT, repeat NOT, named. The table object is (and must be) named, but the reference is made to the table in the bookmark...which is named.

I know that may sound confusing. But persist and I am sure it will eventually become clear. You did in fact get the concept. Good for you.

Galahadoc
11-13-2008, 07:52 PM
"So i should be able to have the checkboxes anywhere now because it's not using the code to simply hide the 'next' table, but instead a specific, now named, table?.."

Correct!

Using "next" for something can work obviously, but also obviously it has a severe limitation. The next whatever does, in fact, have to BE next.

This way, the relationship is between object and object. The Checkbox and a specific table. Once that relationship is properly established, it does not matter where they are in the document. The table can be moved anywhere...the bookmark will automatically adjust.

Be careful though. While yes you can use a "name" to create a table object of a specific table, the table itself is NOT, repeat NOT, named. The table object is (and must be) named, but the reference is made to the table in the bookmark...which is named.

I know that may sound confusing. But persist and I am sure it will eventually become clear. You did in fact get the concept. Good for you.

haha, glad you realised it would sound confusing. I was under the impression that the table was an object? But i think you are right in saying that persistence will bring understanding, what you said appears to root from the real basics of VBA.

Hopefully i have further need for something i didn't believe was possible with an Office application thus giving me further reason to look into this.

Thanks again guys. :]

{ G }

fumei
11-14-2008, 11:25 AM
"I was under the impression that the table was an object? "

Your impression is correct, but fully grasping this is core to understanding VBA.

What, exactly, do you mean by "the table"?

ALL "things" are objects. So, yes, "the table" is an object.

Let's look at an example.

You have a document with, say, five tables in it. Let us consider, say, the third table in the document.

By itself, no, it is not really an object. By itself, that table is just a part of the document - which is of course an object. But, by itself, the table is NOT an object.

Objects must be explicitly identified. Until that specific table is identified, it is NOT an object.

ActiveDocument.Tables(3)

does identify the table, and by doing so, yes, VBA can now use the methods and properties of a table object. So:


ActiveDocument.Tables(3).Cell(2,3).Range.Text = "Blah"


By identifying the third table (using the index number - Tables(3)), you can now use table methods and properties such as .Range.Text.

The problem in Word is that tables are normally identified by Index number, and the index number has ONE source. And only one source.

The order in the document.

Tables(3) means, and ONLY means, "the third table in the document".

It does NOT mean THAT table. In other words, ActiveDocument.Tables(3) - while identifying a table as an object, thus exposing table methods and properties - it only identifies the third table in the document.

It does NOT identify a specific table, as a table. It identifies the third table in the document, regardless of anything else.

So, say you add a table before it.

What was ActiveDocument.Tables(3), is now ActiveDocument.Tables(4).

Again, the Index number means only one thing: the order in the document.

Actions that put tables into the document, or take tables out of the document automatically reset all table Index numbers.

Therefore using Index number can be problematic because any given table can have it Index number changed.

By bookmarking the table (and bookmarks MUST have a name), you can declare a table OBJECT, and then set it as the table in the bookmark.

It is the difference between:

"the third table" and "THAT table"

When you bookmark a table, and then declare and set a table object to the table in the bookmark, the table object IS - and this is important to understand - THAT table. No other table...THAT one.

Therefore, no matter where that table is in the document, no matter what size it is (changed perhaps by adding rows, or columns, deleting rows etc.), the declared and Set table object IS that table. Regardless of its Index number.

Let me reiterate.

Any table in a document is NOT an object until it is identified as an object. Until then, it is a member of a Collection - the Tables collection. Once it is identified - ActiveDocument.Tables(3) - then it is an object. The key here is that the ONLY way to identify it - thus making an object - is by Index number. And Index number can change.

By bookmarking a table, you can identify it by using the name of the bookmark. Thus identification (essential to make and use a table object) is independent of the Index number.

ActiveDocument.Tables(3) identifies the third table, whatever that is.

Assuming the table IS bookmarked, and the bookmark name is "ThirdTable"...


Dim ThirdTable As Table
Set ThirdTable = ActiveDocument.Bookmarks("ThirdTable") _
.Range.Tables(1)

identifies the table in the bookmark ThirdTable.

That table could have its index number changed - it could now be, say, ActiveDocument.Tables(42) - and it would make no difference. Because you are identifying it by its bookmark, NOT its order in the document.




Are we having fun yet?

lucas
11-14-2008, 12:38 PM
Are we having fun yet?

Yes we are Gerry. Your clear explainations have helped me understand much of what makes Word different.

Thanks and keep up the good work my friend.

lucas
11-15-2008, 10:14 AM
A friend saw this and had a need for it but didn't want to use the checkboxes.....attached is a toggle method derived from Gerry's code.

see the menu item next to help on the main menu to run it.

Galahadoc
11-17-2008, 01:57 AM
Cool. I understand what you're talking about now, doesnt mean i can go out and start writing code, but i understand the specific code i'm using now a lot better. Had to read it a few times but i think i've grasped it really well. Thanks.


A friend saw this and had a need for it but didn't want to use the checkboxes.....attached is a toggle method derived from Gerry's code.

see the menu item next to help on the main menu to run it.

That is sweet as! Maybe i'm so impressed because i'm new to this stuff, but that is cool.. :]

{ G }

fumei
11-17-2008, 05:27 AM
"much of what makes Word different."


hmmmmm........

That sounds like a quote I read once.....

Anyhow, to possibly get a better grasp of the table thing, In Steve's demo try moving the tables around. Move Table 2 so it is before Table 1. Add another Table before Table 1. Add another table before Table 2.

What you will see is the the same Table used by the code is still used by the code. That is because the table is idenified by the table in its bookmark, NOT by Table(x) - the Index number.

This is the power of (or one of them) of using bookmarks.

Galahadoc
11-20-2008, 03:58 PM
Hi guys,

any chance you could help on the protection aspect? I need to protect the document so that all you can do is fill in forms - however this causes a problem with the checkboxes as they then make a change that is outside of the protection parameters.

I've uploaded the 2 proposals, they are very similar and both work perfectly except for the whole protection thing.

[edit: well i've uploaded 1 file as it is the maximum allowed. O_O, this is the preferred one anyway]

{ G }

lucas
11-20-2008, 07:46 PM
Protect your document and then change the code that effects the tables.

The code unprotects the document, runs your code and then reprotects the doc.

Sub MyShowHideTable(bolIn As Boolean, strTable As String)
Dim aTable As Table
ActiveDocument.Unprotect Password:="pwd"
Set aTable = ActiveDocument.Bookmarks(strTable) _
.Range.Tables(1)

aTable.Range.Font.Hidden = Not bolIn
Set aTable = Nothing
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, Password:="pwd"
End Sub

example attached....

the password is pwd

Galahadoc
11-20-2008, 07:50 PM
Thanks Lucas! Appreciate it! :D

EDIT: Err.. problem. Now it won't let me open the tables via the checkboxes while it's uprotected.. Which i can deal with, but if there was a way to fix this aswell - well it would be better :P

lucas
11-20-2008, 08:25 PM
This should fix it:

Sub MyShowHideTable(bolIn As Boolean, strTable As String)
Dim aTable As Table
If ActiveDocument.ProtectionType <> wdNoProtection Then
ActiveDocument.Unprotect Password:="pwd"
End If
Set aTable = ActiveDocument.Bookmarks(strTable) _
.Range.Tables(1)

aTable.Range.Font.Hidden = Not bolIn
Set aTable = Nothing
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, Password:="pwd"
End Sub