Xin bản đồ các tỉnh Việt Nam trong file Excel (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Minh Ngọc LH

Thành viên chính thức
Tham gia
14/7/18
Bài viết
71
Được thích
32
Giới tính
Nữ
Chào Đại Gia đình GPE

Mùa Covid em đang muốn thể hiện bản đồ các tỉnh thành của Việt Nam có số ca nhiễm là bao nhiêu khi đưa con trỏ chuột vào và tô màu mỗi tỉnh dựa trên tỷ lệ ca nhiễm

Có anh chị em cô chú bác nào đã có file ý tưởng giống như vậy hoặc có bản đồ từng tỉnh thành (ghép lại thành bản đồ Việt Nam) thì cho em xin ạ

Em cảm ơn nhiều!
 
Nếu ai có phiên bản Excel cũ hơn thì tôi tặng cho tọa độ các tỉnh của Việt Nam - dữ liệu trong các cột A: DX. Hãy kiểm tra lại, tôi kiểm tra thì thấy có dữ liệu cho 64 tỉnh thành.

Từ các tọa độ đó mỗi người tự vẽ theo cách của mình. Tôi tạo mỗi tỉnh là 1 SHAPE (tên Shape là tên tỉnh), chỉ làm ví dụ chơi.

Dữ liệu tọa độ tôi tải từ (bản đồ toàn thế giới).


Sau đó dùng code để lọc ra các tọa độ từ tập tin SVG.
 

File đính kèm

Nếu ai có phiên bản Excel cũ hơn thì tôi tặng cho tọa độ các tỉnh của Việt Nam - dữ liệu trong các cột A: DX. Hãy kiểm tra lại, tôi kiểm tra thì thấy có dữ liệu cho 64 tỉnh thành.

Từ các tọa độ đó mỗi người tự vẽ theo cách của mình. Tôi tạo mỗi tỉnh là 1 SHAPE (tên Shape là tên tỉnh), chỉ làm ví dụ chơi.

Dữ liệu tọa độ tôi tải từ (bản đồ toàn thế giới).


Sau đó dùng code để lọc ra các tọa độ từ tập tin SVG.
Các con số trong đó phải hiểu như thế nào hả bác? Tôi xem mà không hiểu chúng biểu thị cho cái gì mà nhiều vậy?
 
Cảm ơn anh!
trên máy em không hiển thị được (Office 2016)
Anh gửi lại cho em cái bản đồ này được không
View attachment 264745
Bạn tải File về rồi thực hiện như sau:
1/ Mở File Excel và Click vào A1, trên Ribbon vào Insert > 3D Map (xem hình 1).
2/ Khi Click chọn 3D Map thì xuất hiện như hình 2.
3/ Click vào Open để mở to bản đồ Map Việt Nam như hình 3.
4/ Muốn thể hiện bản đồ riêng cho từng huyện để hiện thị xã thì bạn phải thêm danh sách xã vào, sau đó tạo PivotTable rồi sử dụng Slicer mới xem được.

Bạn nhìn bên phải hình 3 muốn Add layer cáigì đó thì tự tìm hiểu để Add những thứ cần khi rê vào nó sẽ xuất hiện nội dung trên bản đồ khi bạn muốn xem.
 

File đính kèm

  • A_1.JPG
    A_1.JPG
    66.3 KB · Đọc: 152
  • A_2.JPG
    A_2.JPG
    35.9 KB · Đọc: 152
  • BD_COVID.png
    BD_COVID.png
    406.9 KB · Đọc: 151
  • BD COVID.xlsx
    BD COVID.xlsx
    167.3 KB · Đọc: 91
Lần chỉnh sửa cuối:
Hình như có 'vấn đề'. Các bản đồ đều không thấy quần đảo Hoàng Sa, Trường Sa.
Xem trên Google Maps vẫn thấy các quần đảo.
Thời điểm này khá 'nhạy cảm' nên chắc cần chú thích hay kiểm duyệt gì đó.
 
Lần chỉnh sửa cuối:
Svg là định dạng đồ hoạ 2D vector có thể co dãn mà không bị giảm chất lượng, bị vỡ như hình ảnh ở dạng points. Các đối tượng trên Web được dựng bởi svg rất nhẹ, mượt, mịn màng.
Đồ hoạ 2D thì các đối tượng xác định bởi toạ độ X,Y.
Có phần mềm chuyên thiết kế cái này, còn với files svg đã có thì cách đơn giản nhất là mở nó bằng trình duyệt web rồi view source là thấy luôn và ngay.
 
Nếu ai có phiên bản Excel cũ hơn thì tôi tặng cho tọa độ các tỉnh của Việt Nam - dữ liệu trong các cột A: DX. Hãy kiểm tra lại, tôi kiểm tra thì thấy có dữ liệu cho 64 tỉnh thành.

Từ các tọa độ đó mỗi người tự vẽ theo cách của mình. Tôi tạo mỗi tỉnh là 1 SHAPE (tên Shape là tên tỉnh), chỉ làm ví dụ chơi.

Dữ liệu tọa độ tôi tải từ (bản đồ toàn thế giới).


Sau đó dùng code để lọc ra các tọa độ từ tập tin SVG.
Cảm ơn bác! Thật tuyệt vời!
 
Tập tin SVG chẳng qua là tập tin text. Chẳng hạn tập tin tải về là vietnamHigh.svg khi mở bằng notepad như hình ở dưới. Ta thấy là các điểm đường biên của vd. Lai Châu bắt đầu từ <path id="VN-01" title="Lai Châu" ... và kết thúc bằng />.
Từ d="M62.06,32.98 ... cho tới hết là mô tả toàn bộ "đường đi" - path.

path
Cho phép tạo ra nhiều loại đường cong, đường đa giác và hình dạng. Thuộc tính d được sử dụng để mô tả lộ trình của đường cong. Mô tả được thực hiện với các lệnh sau: M (dịch chuyển tới điểm tham chiếu), L (đoạn thẳng), H (đoạn ngang), V (đoạn thẳng đứng), Z (đóng - khép kín đường cong, tức nối với điểm đầu tiên), C (đường cong Beizer), đi kèm theo các tham số .

vd.
<path d = "M1,5L3,2L6,4L7,7Z" />

Tức: nhẩy tới điểm (1; 5) -> đi tới điểm (3; 2) -> đi tới (6; 4) -> đi tới (7; 7) -> đi tới điểm đầu tiên.

vd.
<path d = "M1,5L3,2H5V1 ...

Tức: nhẩy tới điểm (1; 5) -> đi tới điểm (3; 2) -> đi ngang tới x = 5 (đi ngang thì y không đổi, y = 2) -> đi dọc tới y = 1 (đi dọc nên x không đổi, x = 5). Điểm hiện hành là (5; 1)

Đoạn đầu của Lai Châu:
<path d="M62.06,32.98L1.76,0.42L1.04,1 ...

Tức: nhẩy tới (62.06; 32.98) -> đi tới (1.76; 0.42) -> -đi tới (1.04; 1)

Biết được cách mô tả trong SVG thì có thể viết code để lọc ra các toạ độ. Trong tập tin Excel tôi đã thay đổi gốc tọa độ, có thể cả scale. Vd. nếu trong các điểm có điểm với x nhỏ nhất là 100, và điểm khác có y nhỏ nhất là 50 thì có thể dời gốc tọa độ tới điểm (100; 50). Lúc này mỗi điểm sẽ có tọa độ x nhỏ bớt 100 và tọa độ y nhỏ bớt 50.

vietnamHigh.jpg
 
Anh thuộc loại lanh lợi rồi. :D
Không biết là khen hay là chê :p
Ngay từ đầu anh nói là autoshape, tôi nghĩ ngay đến toạ độ từng đỉnh của 1 đa giác.
Nếu nói là toạ độ (kinh độ, vĩ độ) thì không vẽ shape được vì đó là toạ độ góc (angle) tính từ tâm trái đất, không phải giá trị number
Nếu quy ra giá trị number giá trị thực thì không vẽ trên excel được vì quá lớn, phải thu nhỏ (scale) về đơn vị pixel.
 
Em đã thực hiện được việc tô màu tự động dự trên số ca nhiễm Covid rồi nhưng phần hiển thị tên tỉnh và số liệu ca nhiễm khi nhấp vào từng tỉnh (hoặc rê con trỏ chuột tới) thì chưa làm được. Nó tương tự hoặc gần giống như khi xem bản đồ Covid Việt nam trong đường dẫn bên dưới. Nhờ GPE giúp em giải quyết vấn đề này ạ. Em cảm ơn nhiều!
vn.jpeg
 

File đính kèm

Cái vụ bản đồ này liên quan tới chính trị.
Nếu chỉ là file cá nhân dùng không sao, còn đăng lên đây là có vấn đề.
Bản đồ trên trang vnexpress vẫn chuẩn có hai quần đảo đó.
BQT nên xem xét sớm vấn đề này, tránh rắc rối (nhắc lần 2).
 
Cái vụ bản đồ này liên quan tới chính trị.
Nếu chỉ là file cá nhân dùng không sao, còn đăng lên đây là có vấn đề.
Bản đồ trên trang vnexpress vẫn chuẩn có hai quần đảo đó.
BQT nên xem xét sớm vấn đề này, tránh rắc rối (nhắc lần 2).
Bác coi lại cho kỹ đi, có thêm Hoàng Sa và Trường sa rồi đó
screenshot_1629990700.png
 
Em đã thực hiện được việc tô màu tự động dự trên số ca nhiễm Covid rồi nhưng phần hiển thị tên tỉnh và số liệu ca nhiễm khi nhấp vào từng tỉnh (hoặc rê con trỏ chuột tới) thì chưa làm được. Nó tương tự hoặc gần giống như khi xem bản đồ Covid Việt nam trong đường dẫn bên dưới. Nhờ GPE giúp em giải quyết vấn đề này ạ. Em cảm ơn nhiều!
Do không phải là biểu đồ (chart) nên không tự động hiển thị. Dùng VBA thì autoshape không có trong sự kiện worksheet selection change, bản thân nó không có sự kiện để bắt.
Tôi phản hồi tới ban quản trị diễn đàn, nếu họ có quan tâm, có xem sẽ biết vấn đề ở đâu.
Các công cụ để vẽ trong chủ đề này lấy từ trên mạng (map chart lấy từ Bing map, 1 bản đồ lấy từ svg map). Người dùng excel không cố ý.
 
Các công cụ để vẽ trong chủ đề này lấy từ trên mạng (map chart lấy từ Bing map, 1 bản đồ lấy từ svg map). Người dùng excel không cố ý
Thì em đã nêu ở bài trước là NÊN chú thích hay gì đó. Bởi cái này nếu dính kiểm duyệt thì với các bài đã đăng kia không cãi được.
 
Thì em đã nêu ở bài trước là NÊN chú thích hay gì đó. Bởi cái này nếu dính kiểm duyệt thì với các bài đã đăng kia không cãi được.
Không đến nỗi thế. Chả lẽ bắt lỗi mọi người đang dùng map chart của excel
 
Không đến nỗi thế. Chả lẽ bắt lỗi mọi người đang dùng map chart của excel
Vụ bản đồ này gần đây được đặc biệt quan tâm.
Nếu nói như anh thì những vụ cài cắm bản đồ đã xử lý đều không bắt lỗi được sao ạ?
Cái này là rơi vào lỗi biết mà không khai báo, biết mà cố tình dùng, có thể thêm lỗi quảng bá trên mạng. Nếu sử dụng ở phạm vi ngoài nước thì đúng là chịu, còn đây đang trong nước mà anh.
Mà thôi, tùy các anh.
 
Vụ bản đồ này gần đây được đặc biệt quan tâm.
Nếu nói như anh thì những vụ cài cắm bản đồ đã xử lý đều không bắt lỗi được sao ạ?
Cái này là rơi vào lỗi biết mà không khai báo, biết mà cố tình dùng, có thể thêm lỗi quảng bá trên mạng. Nếu sử dụng ở phạm vi ngoài nước thì đúng là chịu, còn đây đang trong nước mà anh.
Mà thôi, tùy các anh.
Hai bài trên tôi chỉ mới nói với tư cách cá nhân, để tôi lấy ý kiến ban quản trị rồi xử lý.
Quan điểm tiêng của tôi là "không cố ý". Tôi xài excel và không biết các công cụ vẽ khác, và excel lấy từ Bing nó như thế.
Ví dụ in băng rôn, biểu ngữ, vẽ logo, in tờ rơi, sơn bảng số xe, ... mà không có đầy đủ thì mới là lỗi cố ý.
 
Hai bài trên tôi chỉ mới nói với tư cách cá nhân, để tôi lấy ý kiến ban quản trị rồi xử lý.
Quan điểm tiêng của tôi là "không cố ý". Tôi xài excel và không biết các công cụ vẽ khác, và excel lấy từ Bing nó như thế.
Ví dụ in băng rôn, biểu ngữ, vẽ logo, in tờ rơi, sơn bảng số xe, ... mà không có đầy đủ thì mới là lỗi cố ý.
Bản đồ nước Việt Nam không có 2 quần đảo Hoàng Sa và Trường Sa của Việt Nam, xét về "tình" không thể chấp nhận xét về lý thì vi phạm pháp luật
Diễn đàn có tầm ảnh hưởng khá lớn với đông đảo thành viên, bên an ninh chắc chắn theo dõi các bài đăng, dính tới lỗi bản đồ Việt Nam vì bất cứ lý do nào cũng rất dể bị mời uống trà
 
Em đã thực hiện được việc tô màu tự động dự trên số ca nhiễm Covid rồi nhưng phần hiển thị tên tỉnh và số liệu ca nhiễm khi nhấp vào từng tỉnh (hoặc rê con trỏ chuột tới) thì chưa làm được.
Tôi thử làm cho bạn.

Dùng đồng hồ để kiểm tra xem dưới cursor có phải là Shape không. Nếu đúng thì đọc tên Shape cũng là tên tỉnh. Có tỉnh rồi thì duyệt trong cột W:Y để tìm TodayF0 và TotalF0. 3 thông tin sẽ được hiển thị trên UserForm1. ). Đồng hồ đặt 1 s (1 giây)

1. Code trong modWindowStyle dùng để làm mất thanh tiêu đề và nút X của UserForm. Hàm ChangeFormStyle cũng trả về handle của cửa sổ UserForm1.

2. Code trong Module2 có chứa đồng hồ, phục vụ việc xác định shape dưới cursor và hiển thị thông tin trên UserForm1.

3. Code trong ThisWorkbook và Sheet4 dùng để bật tắt đồng hồ. Ít ra là dụng ý là thế, tôi chưa kiểm tra xem có bật tắt chuẩn không.
 

File đính kèm

Tôi nghĩ là nhiều người làm to chuyện.

Chỉ là ý kiến cá nhân thôi. Tôi không rõ trong hàng ngàn sách báo, bản đồ trên mạng, dùng trong từng cơ quan, tóm lại trong tất cả các bản đồ đang ở đâu đó trong sách báo, giường tủ, trong đất nước Việt Nam, liệu trong tất cả các bản đồ đó đều có Hoàng Sa và Trường Sa. Và sẽ ra sao nếu ngoài Hoàng Sa và Trường Sa ra, nếu bản đồ thiếu một hòn đảo nhỏ tí nào đó (Quảng Ninh?) thì có là vi phạm pháp luật hay không?

Tôi thì cho rằng:

1. Nếu dùng cho cá nhân, trong phạm vi nhỏ, không thuộc loại giáo dục quảng bá rộng rãi (sách giáo khoa?), không để làm chuẩn, nếu có thiếu Hoàng Sa hay Trường Sa thì cùng lắm là THIẾU SÓT.

2. Nếu dùng, hoặc đặc biệt là quảng bá, bản đồ Trung Cộng mà lại có Hoàng Sa hay Trường Sa thì đó là vi phạm pháp luật, là chính trị.

1. là chuyện thiếu sót, nói cho cùng tôi không gán Trường Sa cho Trung Cộng hay bất cứ Lào, Nga ... Còn 2. thì rõ ràng là tôi đã cho là Trường Sa là của Trung Cộng. Hai sự việc là khác nhau, tầm quan trọng là khác nhau.
 
Tôi thử làm cho bạn.

Dùng đồng hồ để kiểm tra xem dưới cursor có phải là Shape không. Nếu đúng thì đọc tên Shape cũng là tên tỉnh. Có tỉnh rồi thì duyệt trong cột W:Y để tìm TodayF0 và TotalF0. 3 thông tin sẽ được hiển thị trên UserForm1. ). Đồng hồ đặt 1 s (1 giây)

1. Code trong modWindowStyle dùng để làm mất thanh tiêu đề và nút X của UserForm. Hàm ChangeFormStyle cũng trả về handle của cửa sổ UserForm1.

2. Code trong Module2 có chứa đồng hồ, phục vụ việc xác định shape dưới cursor và hiển thị thông tin trên UserForm1.

3. Code trong ThisWorkbook và Sheet4 dùng để bật tắt đồng hồ. Ít ra là dụng ý là thế, tôi chưa kiểm tra xem có bật tắt chuẩn không.
Cảm ơn Bác thật nhiều! Bác giỏi quá. Cháu thấy nó chạy được, có điều ở lần mở khác thấy có báo lỗi ở dòng: Application.OnTime lastTime, "doi_mau" ạ. Sau đó tắt đi mở lại thì lại bình thường.
 
Tôi thử làm cho bạn.

Dùng đồng hồ để kiểm tra xem dưới cursor có phải là Shape không. Nếu đúng thì đọc tên Shape cũng là tên tỉnh. Có tỉnh rồi thì duyệt trong cột W:Y để tìm TodayF0 và TotalF0. 3 thông tin sẽ được hiển thị trên UserForm1. ). Đồng hồ đặt 1 s (1 giây)

1. Code trong modWindowStyle dùng để làm mất thanh tiêu đề và nút X của UserForm. Hàm ChangeFormStyle cũng trả về handle của cửa sổ UserForm1.

2. Code trong Module2 có chứa đồng hồ, phục vụ việc xác định shape dưới cursor và hiển thị thông tin trên UserForm1.

3. Code trong ThisWorkbook và Sheet4 dùng để bật tắt đồng hồ. Ít ra là dụng ý là thế, tôi chưa kiểm tra xem có bật tắt chuẩn không.
Mới download file về, mở lên thì báo lỗi này các anh ơi, (em dùng: Win 10 64 bits, Excel 365)

1630024961237.png
 
Tôi thử làm cho bạn.

Dùng đồng hồ để kiểm tra xem dưới cursor có phải là Shape không. Nếu đúng thì đọc tên Shape cũng là tên tỉnh. Có tỉnh rồi thì duyệt trong cột W:Y để tìm TodayF0 và TotalF0. 3 thông tin sẽ được hiển thị trên UserForm1. ). Đồng hồ đặt 1 s (1 giây)

1. Code trong modWindowStyle dùng để làm mất thanh tiêu đề và nút X của UserForm. Hàm ChangeFormStyle cũng trả về handle của cửa sổ UserForm1.

2. Code trong Module2 có chứa đồng hồ, phục vụ việc xác định shape dưới cursor và hiển thị thông tin trên UserForm1.

3. Code trong ThisWorkbook và Sheet4 dùng để bật tắt đồng hồ. Ít ra là dụng ý là thế, tôi chưa kiểm tra xem có bật tắt chuẩn không.
Cháu để ý thấy khi mở file mà có Protected View thì sẽ bị lỗi trên. Còn nếu ko có thì file chạy bình thường
screenshot_1630034505.pngscreenshot_1630034546.png
 
Đây là đề tài hay.

Cảm ơn nhiều người đã quan tâm và nhắc nhở sự nhạy cảm của vấn đề này.

Hiện giờ Bình là người có thể bị gọi tên trong vai trò quản lý diễn đàn. Và Bình không muốn mạo hiểm (hoặc tốn thời gian) cho chuyện này.
Mọi người thông cảm nhé. Trong vòng 1 tiếng đồng hồ, những bản đồ không có TS, HS sẽ bị gở xuống.
Thân
Bình

@hoangminhtien bài của anh đầu tiên trong danh sách bị xem xét. thân.
 
Đây là đề tài hay.

Cảm ơn nhiều người đã quan tâm và nhắc nhở sự nhạy cảm của vấn đề này.

Hiện giờ Bình là người có thể bị gọi tên trong vai trò quản lý diễn đàn. Và Bình không muốn mạo hiểm (hoặc tốn thời gian) cho chuyện này.
Mọi người thông cảm nhé. Trong vòng 1 tiếng đồng hồ, những bản đồ không có TS, HS sẽ bị gở xuống.
Thân
Bình

@hoangminhtien bài của anh đầu tiên trong danh sách bị xem xét. thân.
Nói ra thì cũng là câu chuyện để suy ngẫm. Office 2016 phát hành từ mấy năm rồi, sử dụng rất phổ biến tại Việt Nam, trong đó sử dụng map chart để vẽ biểu đồ Việt Nam mà ko có HS, TS chả thấy ai nói gì... Người ta sử dụng nguồn đó để đăng bài thì bị gắn nhãn?
 
Đây là đề tài hay.

Cảm ơn nhiều người đã quan tâm và nhắc nhở sự nhạy cảm của vấn đề này.

Hiện giờ Bình là người có thể bị gọi tên trong vai trò quản lý diễn đàn. Và Bình không muốn mạo hiểm (hoặc tốn thời gian) cho chuyện này.
Mọi người thông cảm nhé. Trong vòng 1 tiếng đồng hồ, những bản đồ không có TS, HS sẽ bị gở xuống.
Thân
Bình

@hoangminhtien bài của anh đầu tiên trong danh sách bị xem xét. thân.
Những bài nào mà có thể chưa phù hợp, gây rủi do cho diễn đàn thì anh gỡ đi anh ạ.
Tuy nhiên, chúng ta cũng cần phản hồi lại với Microsoft bổ xung Hoàng Sa và Trường Sa với mục map chart này, chứ không diễn đàn ta mãi mãi không được sử dụng nó.
 
Vậy là từ xưa tới nay, đơn vị chủ quản là Bộ Thông tin truyền thông mới phản ánh với google map về HS, TS. Không hiểu họ có nắm được thông tin là Microsoft (Bing map) cũng ko có TS, HS
 
Vậy là từ xưa tới nay, đơn vị chủ quản là Bộ Thông tin truyền thông mới phản ánh với google map về HS, TS. Không hiểu họ có nắm được thông tin là Microsoft (Bing map) cũng ko có TS, HS
Nói chung ta nói ta đúng, họ nói họ đúng - Thế giới thì không có luật chung cho tất cả (nếu có chung cũng chỉ là 1 nhóm nước nào ký với nhau, nói khác đi là rất lỏng lẻo thiếu chế tài, pháp tài)
Dùng hay không là do ta quyết định, nên chọn sản phẩm tốt mà dùng
 
Cháu để ý thấy khi mở file mà có Protected View thì sẽ bị lỗi trên. Còn nếu ko có thì file chạy bình thường
Office của bạn là phiên bản nào? Nếu là 64 bit thì tôi nhờ test hộ phiên bản Covid Viet Nam.xlsm mới. Tôi thay OnTime của VBA bằng SetTimer của Windows API nên muốn kiểm tra khai báo.
 
Cái này hay quá.
Cái này bây giờ mình có thể thêm bản đồ chi tiết của tỉnh hoặc thành phố khi nhấn vào được không ?
 
Hơi tiếc. 32 bit thì 99,99% là chạy rồi, chỉ muốn kiểm tra 64 bit thôi. Đồng hồ bây giờ tôi đặt nhịp 1/5 s, dùng SetTimer thấy mượt, không bị giật giật trỏ chuột.
Của em 64 bit vẫn chạy bình thường ạ. Em dùng office 365
 
Cái này bây giờ mình có thể thêm bản đồ chi tiết của tỉnh hoặc thành phố khi nhấn vào được không ?
Thực ra bài này là bản đồ nhưng lôgíc không hẳn là cho bản đồ. Có tọa độ của thành phố, quận, hay từng thửa đất, căn nhà bạn có thể tạo Shape. Có tọa độ của đa giác bất kỳ bạn tạo được Shape. Bạn có thể tự tạo Shape có hình dạng là hình tròn, êlíp, hình vuông. Có thể tạo Shape mô tả người, đồ vật, con vật v...v. Và dùng code y hệt để tô mầu, hiện thông tin về mỗi con người, con vật, đồ vật đang ở dưới con trỏ chuột. Triết lý của code không dính dáng gì tới bản đồ địa lý.
Bài đã được tự động gộp:

Của em 64 bit vẫn chạy bình thường ạ. Em dùng office 365
Tôi viết rõ mà. Bây giờ tôi thay OnTime bằng SetTimer nên tôi cần kiểm tra khai báo API. Nhiều cái mình không chắc chắn, nhiều cái sơ ý. Nếu có lỗi thì khi kiểm tra trên 64 bit sẽ lòi ra. Còn 32 bit thì tôi đang có và kiểm tra được rồi. Bản trước không nói (có 1 chỗ sơ sót khi khai báo, vd. GetWindowLong trả về LongPtr vào style nhưng style lại khai báo là Long vì thế có lỗi như bài #31), bây giờ dùng SetTimer nên tôi muốn kiểm tra.

Bạn có chấp nhận kiểm tra hộ tôi không?
 
Lần chỉnh sửa cuối:
Thực ra bài này là bản đồ nhưng lôgíc không hẳn là cho bản đồ. Có tọa độ của thành phố, quận, hay từng thửa đất, căn nhà bạn có thể tạo Shape. Có tọa độ của đa giác bất kỳ bạn tạo được Shape. Bạn có thể tự tạo Shape có hình dạng là hình tròn, êlíp, hình vuông. Có thể tạo Shape mô tả người, đồ vật, con vật v...v. Và dùng code y hệt để tô mầu, hiện thông tin về mỗi con người, con vật, đồ vật đang ở dưới con trỏ chuột. Triết lý của code không dính dáng gì tới bản đồ địa lý.
Cái này vượt quá khả năng của tôi rồi, để tôi tìm hiểu thử, ở đây có nhiều bác có kiến thức rộng quá.
 
Hơi tiếc. 32 bit thì 99,99% là chạy rồi, chỉ muốn kiểm tra 64 bit thôi. Đồng hồ bây giờ tôi đặt nhịp 1/5 s, dùng SetTimer thấy mượt, không bị giật giật trỏ chuột.

Bác gửi file làm trên 64bit lên tôi test thử xem nhé, Dùng Timer hiện tại thấy nó cứ nhấp nháy trỏ chuột.
 
Bác gửi file làm trên 64bit lên tôi test thử xem nhé, Dùng Timer hiện tại thấy nó cứ nhấp nháy trỏ chuột.
Bạn kiểm tra hộ nhé.

Để nhiều người khỏi hiểu lầm thì tôi nói rõ. Không phải là tập tin chỉ làm cho 64 bit. Tập tin làm để chạy trên cả 32 bit và 64 bit. 32 bit thì tôi có nên đã kiểm tra rồi. Chỉ không có 64 bit nên muốn nhờ kiểm tra trên 64 bit.

Lưu ý: tập tin hoàn chỉnh ở bài #65
 

File đính kèm

Lần chỉnh sửa cuối:
Bạn kiểm tra hộ nhé.

Để nhiều người khỏi hiểu lầm thì tôi nói rõ. Không phải là tập tin chỉ làm cho 64 bit. Tập tin làm để chạy trên cả 32 bit và 64 bit. 32 bit thì tôi có nên đã kiểm tra rồi. Chỉ không có 64 bit nên muốn nhờ kiểm tra trên 64 bit.

Chú ơi SN ơi, cháu mở lên nó bị lỗi như thế này rồi tắt luôn, hình ảnh cháu phải canh mãi mới chụp được nên thông báo lỗi nó mờ:

1630147849259.png
 
Chú ơi SN ơi, cháu mở lên nó bị lỗi như thế này rồi tắt luôn, hình ảnh cháu phải canh mãi mới chụp được nên thông báo lỗi nó mờ:

View attachment 264949
Trong cửa sổ này có nút Debug. Nếu bạn nhanh tay click vào Debug và cho tôi biết dòng nào bị bôi vàng thì hay quá.

Thực ra tôi không dám chắc khai báo Sub TimerProc.
 
...................................................... nhờ các mod xóa giúp em, đã chuyển bài dưới
 
Lần chỉnh sửa cuối:
Trong cửa sổ này có nút Debug. Nếu bạn nhanh tay click vào Debug và cho tôi biết dòng nào bị bôi vàng thì hay quá.

Thực ra tôi không dám chắc khai báo Sub TimerProc.
cháu ghi lại màn hình chú xem nhé, nhanh quá cháu kịp bấm vào được cái gì cả,hình như là khi đặt chuột ở các ô trên bảng tính thì mới bị, đúng rồi bật lên để không thì không sao nếu di chuyển trên bảng tính là bị lỗi vậy.
 

File đính kèm

cháu ghi lại màn hình chú xem nhé, nhanh quá cháu kịp bấm vào được cái gì cả,hình như là khi đặt chuột ở các ô trên bảng tính thì mới bị, đúng rồi bật lên để không thì không sao nếu di chuyển trên bảng tính là bị lỗi vậy.
Bây giờ tôi hiểu rồi. Nếu bài trước bạn viết rõ thì tôi không hiểu sai.

Tức khi mở tập tin thì di chuột tới ngày tận thế vẫn không có lỗi. Nhưng nếu CLICK để chọn ô nào đó thì có lỗi. Cũng dễ hiểu thôi vì khi CLICK thì sẽ có code của Excel được thực thi, vd. nếu có Sub Worksheet_SelectionChange thì nó sẽ được thực hiện. Trong khi đó đồng thời Windows gọi call back TimerProc. 2 thằng "xung đột" nhau nên sảy ra lỗi.

Khắc phục:
1. Trong sub TimerProc trước dòng GetCursorPos pt thì thêm dòng On Error GoTo end_. Tức phải có
Mã:
On Error GoTo end_
GetCursorPos pt

2. Trước End Sub thên dòng end_:, tức phải có
Mã:
end_:
End Sub


̣Để chỉnh sửa thì thao tác như sau: Mở Excel với tập tin trắng -> File -> Options -> Trust Center -> tắt Macro -> mở Covid -> chỉnh sửa -> lưu lại rồi đóng Covid -> Trust Center -> bật macro -> mở Covid

Bây giờ thế nào?
 
Bạn kiểm tra hộ nhé.

Để nhiều người khỏi hiểu lầm thì tôi nói rõ. Không phải là tập tin chỉ làm cho 64 bit. Tập tin làm để chạy trên cả 32 bit và 64 bit. 32 bit thì tôi có nên đã kiểm tra rồi. Chỉ không có 64 bit nên muốn nhờ kiểm tra trên 64 bit.

Lỗi đây anh.

Screen Shot 2021-08-28 at 17.56.39.png

Sau khi em sửa cái hàm SetStyleBit() thì nó chạy được nhưng thường bị treo và lỗi như video đính kèm.

Screen Shot 2021-08-28 at 13.08.41.png

Link video: https://www.mediafire.com/file/nsr40pdq5arg8nc/Loi_setTimer.7z/file
 
Lỗi đây anh.

View attachment 264956

Sau khi em sửa cái hàm SetStyleBit() thì nó chạy được nhưng thường bị treo và lỗi như video đính kèm.

View attachment 264957

Link video: https://www.mediafire.com/file/nsr40pdq5arg8nc/Loi_setTimer.7z/file
Đúng là kiểu của style không chuẩn. Khi VBA7 thì style là LongPtr (vd. GetWindowLong trả về LongPtr). Nhưng khi dò bằng mắt thì rất dễ sơ ý và bỏ qua.

Tuy nhiên theo tôi thì bạn sửa thế chưa chuẩn. Nếu là tôi thì tôi sửa lại thành
Mã:
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If

Còn lỗi mà bạn 3ii viết thì tôi đã đề nghị sửa như bài #53

Cám ơn bạn bạn đã phát hiện thiếu sót style.
 
Thực ra bài này là bản đồ nhưng lôgíc không hẳn là cho bản đồ. Có tọa độ của thành phố, quận, hay từng thửa đất, căn nhà bạn có thể tạo Shape. Có tọa độ của đa giác bất kỳ bạn tạo được Shape. Bạn có thể tự tạo Shape có hình dạng là hình tròn, êlíp, hình vuông. Có thể tạo Shape mô tả người, đồ vật, con vật v...v. Và dùng code y hệt để tô mầu, hiện thông tin về mỗi con người, con vật, đồ vật đang ở dưới con trỏ chuột. Triết lý của code không dính dáng gì tới bản đồ địa lý.
Bài đã được tự động gộp:


Tôi viết rõ mà. Bây giờ tôi thay OnTime bằng SetTimer nên tôi cần kiểm tra khai báo API. Nhiều cái mình không chắc chắn, nhiều cái sơ ý. Nếu có lỗi thì khi kiểm tra trên 64 bit sẽ lòi ra. Còn 32 bit thì tôi đang có và kiểm tra được rồi. Bản trước không nói (có 1 chỗ sơ sót khi khai báo, vd. GetWindowLong trả về LongPtr vào style nhưng style lại khai báo là Long vì thế có lỗi như bài #31), bây giờ dùng SetTimer nên tôi muốn kiểm tra.

Bạn có chấp nhận kiểm tra hộ tôi không?
Xin lỗi anh, vừa rồi em kiểm tra lại thì đang dùng 32 bit, em vừa update lên 64 bit để xem lỗi gì?
Đây là hình ảnh lỗi ạ (Bôi đen ở chữ style).

Snag_c0ba804.png
 
Đúng là kiểu của style không chuẩn. Khi VBA7 thì style là LongPtr (vd. GetWindowLong trả về LongPtr). Nhưng khi dò bằng mắt thì rất dễ sơ ý và bỏ qua.

Tuy nhiên theo tôi thì bạn sửa thế chưa chuẩn. Nếu là tôi thì tôi sửa lại thành
Mã:
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If

Còn lỗi mà bạn 3ii viết thì tôi đã đề nghị sửa như bài #53

Đã sửa như bài #53 và chạy êm ru.
Em sửa cái hàm SetStyleBit như kiểu trên vì LongPtr vẫn nhận dạng được trong Office 32bit + Windows 64bit (còn trong Windows 32bit + Office 32bit thì không có tạo máy ảo đế test).
 
Bây giờ tôi hiểu rồi. Nếu bài trước bạn viết rõ thì tôi không hiểu sai.

Tức khi mở tập tin thì di chuột tới ngày tận thế vẫn không có lỗi. Nhưng nếu CLICK để chọn ô nào đó thì có lỗi. Cũng dễ hiểu thôi vì khi CLICK thì sẽ có code của Excel được thực thi, vd. nếu có Sub Worksheet_SelectionChange thì nó sẽ được thực hiện. Trong khi đó đồng thời Windows gọi call back TimerProc. 2 thằng "xung đột" nhau nên sảy ra lỗi.

Khắc phục:
1. Trong sub TimerProc trước dòng GetCursorPos pt thì thêm dòng On Error GoTo end_. Tức phải có
Mã:
On Error GoTo end_
GetCursorPos pt

2. Trước End Sub thên dòng end_:, tức phải có
Mã:
end_:
End Sub


̣Để chỉnh sửa thì thao tác như sau: Mở Excel với tập tin trắng -> File -> Options -> Trust Center -> tắt Macro -> mở Covid -> chỉnh sửa -> lưu lại rồi đóng Covid -> Trust Center -> bật macro -> mở Covid

Bây giờ thế nào?

Tuyệt vời cảm ơn chú, code chạy êm ru, còn khúc dưới đây cháu chưa hiểu các Sao đang bàn về chuyện gì:
Lỗi đây anh.

View attachment 264956

Sau khi em sửa cái hàm SetStyleBit() thì nó chạy được nhưng thường bị treo và lỗi như video đính kèm.

View attachment 264957

Link video: https://www.mediafire.com/file/nsr40pdq5arg8nc/Loi_setTimer.7z/file
Đúng là kiểu của style không chuẩn. Khi VBA7 thì style là LongPtr (vd. GetWindowLong trả về LongPtr). Nhưng khi dò bằng mắt thì rất dễ sơ ý và bỏ qua.

Tuy nhiên theo tôi thì bạn sửa thế chưa chuẩn. Nếu là tôi thì tôi sửa lại thành
Mã:
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If

Còn lỗi mà bạn 3ii viết thì tôi đã đề nghị sửa như bài #53

Cám ơn bạn bạn đã phát hiện thiếu sót style.

rút cục là có phải sửa gì nữa không sửa khúc nào xin hãy nói rõ để cháu biết hoặc gửi file đính kèm.
 
Tuyệt vời cảm ơn chú, code chạy êm ru, còn khúc dưới đây cháu chưa hiểu các Sao đang bàn về chuyện gì:

rút cục là có phải sửa gì nữa không sửa khúc nào xin hãy nói rõ để cháu biết hoặc gửi file đính kèm.
Sửa chứ, các bài đều bàn về code của Covid mà.

Trong modWindowStyle có
Mã:
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)

Sửa thành
Mã:
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If

Tóm lại ngoài khai báo style có thiếu sót thì khi CLICK trên sheet có lỗi là do có "xung đột".

Giải thích thêm cho những người thích Windows API hiểu.

1. Tại sao trong tập tin dùng OnTime không có lỗi khi CLICK trên sheet? OnTime dùng để chạy sub doi_mau. OnTime của VBA nên do Excel chạy, cứ sau 1 s thì Excel sẽ gọi doi_moi. Khi Excel bận thì dù 1 s đã qua thì nó cũng không gọi doi_moi mà làm xong các việc bận mới gọi doi_moi. Excel tự gọi nên nó làm chủ được tình huống. Không có xung đột gì ở đây.

2. Tại sao dùng SetTimer của Windows API thì lỗi khi CLICK trên sheet?
Ta phân tích dòng code
Mã:
ID = SetTimer(0, 0, 200, AddressOf TimerProc)
Dòng code trên có nghĩa là ta đã gọi hàm SetTimer của system Windows, kiểu như: báo cáo sếp (Windows), tôi đặt nhiệm vụ là cứ 200 ms thì thực hiện code của tôi, tức TimerProc, ở địa chỉ xyz trong bộ nhớ. Lúc đó system Windows sẽ tạo 1 "đồng hồ", cứ 200 ms sẽ gọi sub TimerProc. Tất nhiên 200 ms là thời gian mặc định. Khi 200 ms trôi qua mà đúng lúc system bận (ngoài process của ta còn vô vàn process khác trong system, bản thân system có những lúc bận) thì system sẽ gọi TimerProc vào lúc sau. Nhưng đây là nói về việc system bận, còn chuyện Excel lúc đó có bận hay không thì system không quan tâm, cứ 200 ms là gọi TimerProc. Hàm SetTimer trả về một giá trị được ghi nhớ trong biến ID. Khi cần "hủy" đồng hồ thì gọi KillTimer và truyền ID vào để hủy đồng hồ. Tại sao KillTimer không đủ để hủy đồng hồ mà lại phải truyền ID vào? Đơn giản là mỗi app có thể tạo nhiều đồng hồ do có nhu cầu. Khi muốn hủy 1 đồng hồ nào đấy mà chỉ cần gọi KillTimer không có tham số thì cụ thánh của system Windpows cũng chịu không biết "người ta" cần hủy đồng hồ nào. Vì thế mỗi đồng hồ được tạo bởi SetTimer sẽ được gán cho một con số định danh, và SetTimer khi tạo đồng hồ sẽ trả về con số định danh (ID) đó của đồng hồ được tạo. Khi cần hủy đồng hồ nào thì gọi KillTimer và truyền con số định danh (ID) của nó vào.
Khi chạy chương trình thì code và dữ liệu (data) sẽ được load vào bộ nhớ. Mọi chuyện sảy ra là sảy ra trong bộ nhớ. Sub TimerProc nằm đâu đó trong bộ nhớ. Trong trường hợp này TimerProc được gọi bởi system Windows chứ không bởi Excel. Vì mình có "khai báo" gì với Excel đâu mà nó biết khi nào phải gọi cái gọi là TimerProc. Để Windows có thể gọi TimerProc thì phải cung cấp cho Windows địa chỉ của TimerProc trong bộ nhớ. Windows biết TimerProc ở đâu thì cứ "đến giở" là gọi nó thôi. Ta cung cấp cho Windows địa chỉ trong RAM của TimerProc bằng hàm: AddressOf TimerProc sẽ trả về địa chỉ của TimerProc trong RAM. Khi đến giờ là Windows gọi TimerProc để thực thi. Nếu đúng lúc đó người dùng CLICK trên sheet thì code của Excerl cũng được thực thi (nếu vd. Excel phát hiện có Worksheet_SelectionChange thì code của Worksheet_SelectionChange sẽ được thực thi). 2 vị khác nhau cùng thực hiện việc của mình thì sảy ra "xung đột".

Hàm mà khi gọi một hàm nào đó của Windows API ta phải cung cấp cho Windows địa chỉ của nó, để Windows biết nó nằm ở đâu trong RAM để sau đó gọi nó, hàm đó được gọi là call back. TimerProc là một call back.
 
Lần chỉnh sửa cuối:
Sửa chứ, các bài đều bàn về code của Covid mà.

Trong modWindowStyle có
Mã:
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)

Sửa thành
Mã:
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If

Tóm lại ngoài khai báo style có thiếu sót thì khi CLICK trên sheet có lỗi là do có "xung đột".

Giải thích thêm cho những người thích Windows API hiểu.

1. Tại sao trong tập tin dùng OnTime không có lỗi khi CLICK trên sheet? OnTime dùng để chạy sub doi_mau. OnTime của VBA nên do Excel chạy, cứ sau 1 s thì Excel sẽ gọi doi_moi. Khi Excel bận thì dù 1 s đã qua thì nó cũng không gọi doi_moi mà làm xong các việc bận mới gọi doi_moi. Excel tự gọi nên nó làm chủ được tình huống. Không có xung đột gì ở đây.

2. Tại sao dùng SetTimer của Windows API thì lỗi khi CLICK trên sheet?
Ta phân tích dòng code
Mã:
ID = SetTimer(0, 0, 200, AddressOf TimerProc)
Dòng code trên có nghĩa là ta đã gọi hàm SetTimer của system Windows, kiểu như: báo cáo sếp (Windows), tôi đặt nhiệm vụ là cứ 200 ms thì thực hiện code của tôi, tức TimerProc, ở địa chỉ xyz trong bộ nhớ. Lúc đó system Windows sẽ tạo 1 "đồng hồ", cứ 200 ms sẽ gọi sub TimerProc. Tất nhiên 200 ms là thời gian mặc định. Khi 200 ms trôi qua mà đúng lúc system bận (ngoài process của ta còn vô vàn process khác trong system, bản thân system có những lúc bận) thì system sẽ gọi TimerProc vào lúc sau. Nhưng đây là nói về việc system bận, còn chuyện Excel lúc đó có bận hay không thì system không quan tâm, cứ 200 ms là gọi TimerProc. Hàm SetTimer trả về một giá trị được ghi nhớ trong biến ID. Khi cần "hủy" đồng hồ thì gọi KillTimer và truyền ID vào để hủy đồng hồ. Tại sao KillTimer không đủ để hủy đồng hồ mà lại phải truyền ID vào? Đơn giản là mỗi app có thể tạo nhiều đồng hồ do có nhu cầu. Khi muốn hủy 1 đồng hồ nào đấy mà chỉ cần gọi KillTimer không có tham số thì cụ thánh của system Windpows cũng chịu không biết "người ta" cần hủy đồng hồ nào. Vì thế mỗi đồng hồ được tạo bởi SetTimer sẽ được gán cho một con số định danh, và SetTimer khi tạo đồng hồ sẽ trả về con số định danh (ID) đó của đồng hồ được tạo. Khi cần hủy đồng hồ nào thì gọi KillTimer và truyền con số định danh (ID) của nó vào.
Khi chạy chương trình thì code và dữ liệu (data) sẽ được load vào bộ nhớ. Mọi chuyện sảy ra là sảy ra trong bộ nhớ. Sub TimerProc nằm đâu đó trong bộ nhớ. Trong trường hợp này TimerProc được gọi bởi system Windows chứ không bởi Excel. Vì mình có "khai báo" gì với Excel đâu mà nó biết khi nào phải gọi cái gọi là TimerProc. Để Windows có thể gọi TimerProc thì phải cung cấp cho Windows địa chỉ của TimerProc trong bộ nhớ. Windows biết TimerProc ở đâu thì cứ "đến giở" là gọi nó thôi. Ta cung cấp cho Windows địa chỉ trong RAM của TimerProc bằng hàm: AddressOf TimerProc sẽ trả về địa chỉ của TimerProc trong RAM. Khi đến giờ là Windows gọi TimerProc để thực thi. Nếu đúng lúc đó người dùng CLICK trên sheet thì code của Excerl cũng được thực thi (nếu vd. Excel phát hiện có Worksheet_SelectionChange thì code của Worksheet_SelectionChange sẽ được thực thi). 2 vị khác nhau cùng thực hiện việc của mình thì sảy ra "xung đột".

Hàm mà khi gọi một hàm nào đó của Windows API ta phải cung cấp cho Windows địa chỉ của nó, để Windows biết nó nằm ở đâu trong RAM để sau đó gọi nó, hàm đó được gọi là call back. TimerProc là một call back.
Hay quá code vẫn chạy êm như tiếng hát ru chú ạ.
Chú ơi cháu thấy có một vấn đề khi chỉ vào bản đồ (vùng màu xanh) vùng này có phải là Hà Nội không mà không xuất hiện thông tin tên thành phố chú nhỉ? Khi chỉ đến vùng khác thì hiển thị, hình ảnh là cháu đang chỉ vào Nam Định sau đó di chuyển về vùng xanh thông tin trên cái form hiển thị không thay đổi vẫn hiện Nam Định. Như vậy là có phải là vấn đề hay không chú nhỉ, cháu chưa hiểu cái món này:

1630211664737.png
 
Hay quá code vẫn chạy êm như tiếng hát ru chú ạ.
Chú ơi cháu thấy có một vấn đề khi chỉ vào bản đồ (vùng màu xanh) vùng này có phải là Hà Nội không mà không xuất hiện thông tin tên thành phố chú nhỉ? Khi chỉ đến vùng khác thì hiển thị, hình ảnh là cháu đang chỉ vào Nam Định sau đó di chuyển về vùng xanh thông tin trên cái form hiển thị không thay đổi vẫn hiện Nam Định. Như vậy là có phải là vấn đề hay không chú nhỉ, cháu chưa hiểu cái món này:

View attachment 264992
À, cái này là do lỗi khi tạo bản đồ. Vùng xanh hình như là Hà Tây cũ. Cái vùng đỏ tiếp giáp vùng xanh hình như là Hà Nội cũ. Bây giờ 2 vùng tạo nên Hà Nội hiện hành.
Lấy vd. Quảng Ninh. Bạn click vào 1 đảo bất kỳ thì thấy hiện Quảng Ninh ở Name Box. Nhưng click lần nữa vẫn đảo đó thì lại là Freeform ... Tương tự với đảo khác của Quảng Ninh. Như vậy có nhiều Freeform ... khác nhau và chúng được Group với nhau tạo nên 1 vùng "lớn" có tên Quảng Ninh. Như vậy là Quảng Ninh (được tạo từ nhiều vùng nhỏ - freeform) được tạo rất chuẩn. Hà Nội không được tạo chuẩn như thế. Tôi nghĩ cần tạo lại cho chuẩn.
 
Ồ nghĩa là chú lại đau đầu thêm rồi,vậy làm phiền chú thêm một lần nữa.
Tập tin đính kèm là phiên bản mới nhất. Đã sửa các lỗi xuất hiện trong tập tin bài #48, và đã sửa lại bản đồ của Hà Nội.

Bạn kiểm tra lại và báo cáo nhé.
 

File đính kèm

Tập tin đính kèm là phiên bản mới nhất. Đã sửa các lỗi xuất hiện trong tập tin bài #48, và đã sửa lại bản đồ của Hà Nội.

Bạn kiểm tra lại và báo cáo nhé.
Báo cáo chú, cháu đã thử sau: mở loa to, di chuyển các ô, nhập liệu tô màu , thao tác, thậm trí tô cả màu bản đồ sang ánh nắng vàng rực rỡ... rồi trỏ di chuyển chuột nó vẫn đổ lại màu xanh
Sau đó update , màu vàng rực rỡ đã mất. Kết luận: kết quả hơn cả mong đợi, code hoạt động êm loa không phát ra tiếng binh bong, màn hình không hiển thị lỗi.
Đã nhìn thấy tên thủ đô "Hà Nội",cảm ơn chú rất nhiều, file này của chú cháu đã lưu vào thư mục yêu thích.
 
Lần chỉnh sửa cuối:
Vẽ 1 tỉnh lâu lắm luôn. Không biết có thể cho vẽ nhanh hơn được không nhỉ?
1. Tôi nghe chủ thớt nói là trong bảng tọa độ của tôi có cả Hà Tây (cũ). Nếu thế thì theo tôi hiểu Hà Nội mới là Hà Nội trong bảng + Hà Tây trong bảng.

2. Để vẽ mỗi tỉnh mà dùng bảng tọa độ của tôi thì hơi khó với các tỉnh gồm nhiều vùng tách biệt, vd. Quảng Ninh. Quảng Ninh có nhiều đảo, và mỗi đảo là 1 vùng riêng biệt. Từ bảng của tôi khó nhìn thấy nó có những vùng nào.

3. Do tôi viết code lọc tọa độ từ tập tin SVG nên vd. khi gặp Quảng Ninh thì trong quá trình lọc có thể biết đoạn vừa lọc là 1 vùng hoàn chỉnh hay không. Lúc đó thì vẽ luôn vùng. Sau đó nếu tỉnh hiện hành vẫn chưa kết thúc lộ trình thì lại lọc tọa độ cho vùng mới và vẽ vùng đó. Tức code của tôi vừa lọc tọa độ từ tập tin SVG vừa vẽ luôn từng tỉnh, và trong mỗi tỉnh vẽ từng vùng. Tất nhiên khi vẽ xong các vùng cho 1 tỉnh thì gộp (Group) chúng lại.

4. Vẽ 1 vùng hoàn chỉnh - đóng kín.
Giả sử có mảng 2 chiều, mỗi dòng là toạ độ 1 điểm, cột 1 là X, cột 2 là Y. Giả sử mảng có tên là points, số dòng - điểm là count thì hàm create_shape sẽ vẽ shape trên sheet sh, và trả về shape đó. Cách gọi
Mã:
mảng tên các vùng(i) = create_shape(sh, points, count, scale_, offsetX, offsetY).Name

Code của hàm
Mã:
Private Function create_shape(sh As Worksheet, arrPolygon() As Double, ByVal count As Long, ByVal scale_ As Double, ByVal offsetX As Double, ByVal offsetY As Double) As Shape
Dim r As Long
    For r = 1 To count
        arrPolygon(r, 1) = (arrPolygon(r, 1) + offsetX) * scale_
        arrPolygon(r, 2) = (arrPolygon(r, 2) + offsetY) * scale_
    Next r
    With sh
        With .Shapes.BuildFreeform(msoEditingCorner, arrPolygon(1, 1), arrPolygon(1, 2))
            For r = 2 To count
                .AddNodes msoSegmentLine, msoEditingAuto, arrPolygon(r, 1), arrPolygon(r, 2)
            Next r
            Set create_shape = .ConvertToShape
        End With
    End With
End Function

Với cách dùng BuildFreeform và vân vân mây mây thì rất nhanh. Tôi vẽ cả VN còn nhanh hơn bạn vẽ Hà Nội.

Tôi chọn Const scale_ = 1, offsetX = 100, offsetY = 150. scale_ càng nhỏ thì các tọa độ dùng để vẽ sẽ càng nhỏ so với toạ độ trong SVG, tức shape càng nhỏ. offsetX càng lớn thì shape trên sheet sẽ càng dịch xuống dưới, offsetY càng lớn thì shape sẽ càng dịch sang bên phải.

5. Tôi không vẽ lại Hà Nội. Trên bản đồ của chủ thớt đã có 2 vùng. Tôi chỉ sửa thôi.
Click vùng xanh ở bài 61 thì nhìn Name Box bạn sẽ thấy Hà Nội. Nhưng click lần nữa thì ở Name Box lại là b. Click tương tự vùng đỏ giáp với vùng xanh thì có Hà Nội, nhưng click lần nữa thì lại là a. a và b được gộp (Group) thành shape "lớn" có tên là Hà Nội. Nếu click 1 lần vào các đảo của Quảng Ninh thì ở Name Box luôn có Quảng Ninh. Nhưng click lần 2 thì là Freeform ...

Vấn đề ở chỗ với code
Mã:
Set obj = ActiveWindow.RangeFromPoint(pt.x, pt.y)
thì obj.Name lại không là Quảng Ninh mà là Freeform ..., còn với Hà Nội thì obj.Name là a hoặc b. Vì lý do này mà tôi phải mất công từ Freeform ... (Quảng Ninh và các tỉnh có nhiều vùng tương tự) suy ra tên tỉnh là Quảng Ninh bằng code
Mã:
shapeName = obj.Name    ' (A)
        If InStr(1, obj.Name, "Freeform", vbTextCompare) = 1 Then
            For Each shp In Sheet4.Shapes
                If shp.Type = msoGroup Then
                    For Each item In shp.GroupItems
                        If item.Name = shapeName Then
                            shapeName = shp.Name    ' (B)
                            timthay = True
                            Exit For
                        End If
                    Next item
                    If timthay Then Exit For
                End If
            Next shp
        End If

Tức nếu obj.Name không có đoạn đầu là "Freeform" thì đó cũng chính là tên nhóm (Group) - tên tỉnh (ở dòng (A)). Trong trường hợp ngược lại thì tên tỉnh được sửa lại ở dòng (B). Hiểu được đoạn code này thì sửa dễ dàng.

Ai muốn tự làm để kiểm nghiệm, thỏa trí tò mò thì làm như sau: click 2 lần (2 lần chứ không phải là đúp) vào Hà Nội cũ -> trong Name Box có a -> sửa thành vd. Freeform 999. Click 2 lần vào Hà Tây cũ -> trong Name Box có b -> sửa thành vd. Freeform 1000. Bây giờ obj.Name sẽ là Freeform 999 hoặc Freeform 1000 và tên tỉnh sẽ được trả về ở dòng (B).
 
Lần chỉnh sửa cuối:
@batman1 :
Tôi biết rồi:
Do tôi ghi macro, thấy nó cho msoSegmentCurve thì tôi dùng nó. Nhưng nay thấy code của bác tôi thay msoSegmentCurve bằng msoSegmentLine là vẽ nhanh liền.

P/S: Bác cho tôi xin dãy tọa độ của Hà Nội gộp với Hà Tây với bác!
 
@batman1 :
Tôi biết rồi:
Do tôi ghi macro, thấy nó cho msoSegmentCurve thì tôi dùng nó. Nhưng nay thấy code của bác tôi thay msoSegmentCurve bằng msoSegmentLine là vẽ nhanh liền.

P/S: Bác cho tôi xin dãy tọa độ của Hà Nội gộp với Hà Tây với bác!
Do tôi lọc từ SVG nên luôn có riêng rẽ Hà Tây và Hà Nội. Nếu bạn muốn thì bạn hãy thử gộp bằng tay: copy dữ liệu của Hà Tây (cột U:V) rồi paste nối tiếp vào Hà Nội (DS: DT). Để ý thấy là điểm đầu và điểm cuối của Hà Tây có tọa độ như nhau (x, y). Tức lộ trình là khép kín. Tương tự với Hà Nội.
Tôi không thử gộp dữ liệu nên không biết.
 
Do tôi lọc từ SVG nên luôn có riêng rẽ Hà Tây và Hà Nội. Nếu bạn muốn thì bạn hãy thử gộp bằng tay: copy dữ liệu của Hà Tây (cột U:V) rồi paste nối tiếp vào Hà Nội (DS: DT). Để ý thấy là điểm đầu và điểm cuối của Hà Tây có tọa độ như nhau (x, y). Tức lộ trình là khép kín. Tương tự với Hà Nội.
Tôi không thử gộp dữ liệu nên không biết.
Chép nối Hà Tây vào Hà Nội thì sẽ có 1 đường biên ở giữa, hơi kỳ. Nhưng tìm bằng mắt thường thì không biết bỏ điểm nào.
 
Chép nối Hà Tây vào Hà Nội thì sẽ có 1 đường biên ở giữa, hơi kỳ. Nhưng tìm bằng mắt thường thì không biết bỏ điểm nào.
Tôi nghĩ đường biên không đáng sợ lắm. Bạn thử vẽ cho Quảng Ninh xem sao. Tôi sợ là sẽ có các ĐƯỜNG NỐI.

2 vùng khác nhau có thể được ĐƯỢC NỐI với nhau (Code của bạn vẽ một mạch từ tọa độ đầu tới cuối nên khi đến điểm cuối của vùng 1 thì code có thể vẽ đường nối nó với điểm đầu của vùng 2 tiếp theo). Bạn thử vẽ Quảng Ninh xem có vô vàn đường nối ấy không. Chính vì thế trong code của mình tôi vẽ từng vùng riêng rẽ, sau mới Group chúng lại.

Còn chuyện đường biên thì ngồi dò bằng tay bằng mắt để bỏ bớt tọa độ thì tôi không có kiên nhẫn.
 
Lần chỉnh sửa cuối:
Tôi nghĩ đường biên không đáng sợ lắm. Bạn thử vẽ cho Quảng Ninh xem sao. Tôi sợ là sẽ có các ĐƯỜNG NỐI.

2 vùng khác nhau có thể được ĐƯỢC NỐI với nhau (Code của bạn vẽ một mạch từ tọa độ đầu tới cuối nên khi đến điểm cuối của vùng 1 thì code có thể vẽ đường nối nó với điểm đầu của vùng 2 tiếp theo). Bạn thử vẽ Quảng Ninh xem có vô vàn đường nối ấy không. Chính vì thế trong code của mình tôi vẽ từng vùng riêng rẽ, sau mới Group chúng lại.

Còn chuyện đường biên thì ngồi dò bằng tay bằng mắt để bỏ bớt tọa độ thì tôi không có kiên nhẫn.
Rồi thì cũng bỏ được các đoạn tọa độ chồng lấn để gộp Hà Tây vào Hà Nội. Tôi gửi lại file vẽ bản đồ.
 

File đính kèm

Xin cho tôi hỏi, giờ tôi muốn lấy toạ độ của các quận của TP.HCM thì tôi có thể vào đâu lấy. Cám ơn các bác
 
Xin cho tôi hỏi, giờ tôi muốn lấy toạ độ của các quận của TP.HCM thì tôi có thể vào đâu lấy. Cám ơn các bác
Chả vào đâu cả. Tọa độ mà tôi đính kèm là cho 1 tỉnh, không chia ra thành quận, huyện. Bạn muốn có quận huyện thì tìm nguồn khác thôi.
 
Rồi thì cũng bỏ được các đoạn tọa độ chồng lấn để gộp Hà Tây vào Hà Nội. Tôi gửi lại file vẽ bản đồ.
Ồ thì ra vậy, cái bản đồ là tự dùng chỉ số tọa độ để vẽ,bái phục các bác.
Nếu vẽ được như vậy thì bài này của chú BATMAN:
Tập tin đính kèm là phiên bản mới nhất. Đã sửa các lỗi xuất hiện trong tập tin bài #48, và đã sửa lại bản đồ của Hà Nội.

Bạn kiểm tra lại và báo cáo nhé.
Chú xem có thể kết hợp thêm chức năng vẽ lại bản đồ được không ạ, khi chiều cháu test co kéo rồi xóa bản đồ, xong phải tải lại file của chú,nếu có nút cập nhật lại ảnh bản đồ nữa thì hoàn hảo quá.
 
Ồ thì ra vậy, cái bản đồ là tự dùng chỉ số tọa độ để vẽ,bái phục các bác.
Nếu vẽ được như vậy thì bài này của chú BATMAN:

Chú xem có thể kết hợp thêm chức năng vẽ lại bản đồ được không ạ, khi chiều cháu test co kéo rồi xóa bản đồ, xong phải tải lại file của chú,nếu có nút cập nhật lại ảnh bản đồ nữa thì hoàn hảo quá.
Nguyên tắc là: tất cả các dữ liệu, tập tin các loại (excel, ảnh, video, âm nhạc ...) mà khi mất đi thì không thể kiếm lại được (tải từ trên mạng nhưng link đã chết), hoặc phải mất rất nhiều công sức thời gian tiền bạc tìm kiếm để tải lại hoặc tự làm lại, tất cả những tập tin có tầm quan trọng như thế đều phải có bản sao. Nhiều khi 1 bản sao trên đĩa cứng chưa đủ mà còn cả bản sao ở DVD, USB, tùy vào tầm quan trọng mà ghi nhiều bản sao. Lý do rất đơn giản: có thể mất tập tin do sửa chữa và lưu nhầm, vi rút, DVD, USB hỏng.

Vậy thì hãy làm bản sao. Khi nhầm lẫn không phải vào GPE để tải lại. Nguyên tắc của tôi là thế.
 
Nguyên tắc là: tất cả các dữ liệu, tập tin các loại (excel, ảnh, video, âm nhạc ...) mà khi mất đi thì không thể kiếm lại được (tải từ trên mạng nhưng link đã chết), hoặc phải mất rất nhiều công sức thời gian tiền bạc tìm kiếm để tải lại hoặc tự làm lại, tất cả những tập tin có tầm quan trọng như thế đều phải có bản sao. Nhiều khi 1 bản sao trên đĩa cứng chưa đủ mà còn cả bản sao ở DVD, USB, tùy vào tầm quan trọng mà ghi nhiều bản sao. Lý do rất đơn giản: có thể mất tập tin do sửa chữa và lưu nhầm, vi rút, DVD, USB hỏng.

Vậy thì hãy làm bản sao. Khi nhầm lẫn không phải vào GPE để tải lại. Nguyên tắc của tôi là thế.
Chú nói rất chuẩn, cháu sẽ ghi nhớ nguyên tác này.Chú đúng là siêu nhân BATMAN, 1h20 đêm rồi chú vẫn còn hoạt động.
 
Chú nói rất chuẩn, cháu sẽ ghi nhớ nguyên tác này.Chú đúng là siêu nhân BATMAN, 1h20 đêm rồi chú vẫn còn hoạt động.
Ở Việt Nam 1:20 thì ở chỗ tôi mới là 20:20 ngày hôm trước. :D

Mà thôi, tôi viết cho bạn code tạo bản đồ từ dữ liệu tọa độ. Nếu các dữ liệu đó là của Nga thì vẽ bản đồ Nga, nếu dữ liệu là của Việt Nam thì vẽ bản đồ Việt Nam. Hiên trong tập tin đính kèm là dữ liệu của Việt Nam. Nếu cần vẽ bản đồ Nga thì từ dòng 1 và từ cột A phải nhập dữ liệu của Nga.

Nếu tên tỉnh ở A2 được tìm thấy ở dòng 1 của sheet vietnamHigh thì bản đồ tỉnh sẽ được vẽ. Nếu A2 rỗng thì vẽ bản đồ toàn Việt Nam. Nếu tên tỉnh ở A2 khác rỗng nhưng không tìm thấy được ở dòng 1 của sheet vietnamHigh, vd. tên nhập sai, thì A2 sẽ bị xóa và vẽ bản đồ toàn Việt Nam.

Nếu muốn vẽ bản đồ to nhỏ thì sửa scale_. Vd. scale_ = 2 thì bản đồ to gấp đôi. Nếu offsetX và offsetY tăng thì bản đồ sẽ dịch xuống dưới và dịch sang phải.

Trong tập tin dữ liệu cho Hà Nội đã được gộp từ Hà Nội cũ và Hà Tây cũ.

Code cũng đơn giản thôi. Toàn bộ code trong Module1
Mã:
Option Explicit

Sub create_map()
Const scale_ = 1
Const offsetX = 10
Const offsetY = 10
Dim firstRow As Long, lastRow As Long, chiso1 As Long, chiso2 As Long, curr_col As Long, k As Long, n As Long
Dim shp_name() As String, ten As String, Points(), shp As Shape
    ten = Sheet1.Range("A2").Value
    For k = 1 To 63
        If Sheet4.Cells(1, 2 * k - 1).Value = ten Then Exit For
    Next k
    If k > 63 Then
        Sheet1.Range("A2").Value = Empty    ' khong tim thay ten tinh nen xoa ten tinh
        chiso1 = 1
        chiso2 = 63
    Else
        chiso1 = k
        chiso2 = k
    End If
 
    For k = chiso1 To chiso2
        n = 0
        curr_col = 2 * k - 1
        firstRow = Rows.count
        Do While firstRow > 2
            lastRow = firstRow - 1
            lastRow = Sheet4.Cells(lastRow, curr_col + 1).End(xlUp).Row
            firstRow = Sheet4.Cells(lastRow, curr_col + 1).End(xlUp).Row
            n = n + 1
            ReDim Preserve shp_name(1 To n)
            Points = Sheet4.Range(Sheet4.Cells(firstRow, curr_col), Sheet4.Cells(lastRow, curr_col + 1)).Value
            shp_name(n) = create_shape(Sheet1, Points, UBound(Points, 1), scale_, offsetX, offsetY).Name
        Loop
        If UBound(shp_name) = 1 Then
            Set shp = Sheet1.Shapes(shp_name(1))
        Else
            Set shp = Sheet1.Shapes.Range(shp_name).Group
        End If
        With shp
            .Name = Sheet4.Cells(1, curr_col).Value
            .Fill.ForeColor.RGB = RGB(141, 180, 226)
            .Line.Weight = 0.25
            .Line.ForeColor.RGB = RGB(255, 255, 255)
            .Placement = xlMove
        End With
    Next k
End Sub

Private Function create_shape(sh As Worksheet, arrPolygon(), ByVal count As Long, ByVal scale_ As Double, ByVal offsetX As Double, ByVal offsetY As Double) As Shape
Dim r As Long
    For r = 1 To count
        arrPolygon(r, 1) = (arrPolygon(r, 1) + offsetX) * scale_
        arrPolygon(r, 2) = (arrPolygon(r, 2) + offsetY) * scale_
    Next r
    With sh
        With .Shapes.BuildFreeform(msoEditingCorner, arrPolygon(1, 1), arrPolygon(1, 2))
            For r = 2 To count
                .AddNodes msoSegmentLine, msoEditingAuto, arrPolygon(r, 1), arrPolygon(r, 2)
            Next r
            Set create_shape = .ConvertToShape
        End With
    End With
End Function
 

File đính kèm

Lần chỉnh sửa cuối:
Ở Việt Nam 1:20 thì ở chỗ tôi mới là 20:20 ngày hôm trước. :D

Mà thôi, tôi viết cho bạn code tạo bản đồ từ dữ liệu tọa độ. Nếu các dữ liệu đó là của Nga thì vẽ bản đồ Nga, nếu dữ liệu là của Việt Nam thì vẽ bản đồ Việt Nam. Hiên trong tập tin đính kèm là dữ liệu của Việt Nam. Nếu cần vẽ bản đồ Nga thì từ dòng 1 và từ cột A phải nhập dữ liệu của Nga.

Nếu tên tỉnh ở A2 được tìm thấy ở dòng 1 của sheet vietnamHigh thì bản đồ tỉnh sẽ được vẽ. Nếu A2 rỗng thì vẽ bản đồ toàn Việt Nam. Nếu tên tỉnh ở A2 khác rỗng nhưng không tìm thấy được ở dòng 1 của sheet vietnamHigh, vd. tên nhập sai, thì A2 sẽ bị xóa và vẽ bản đồ toàn Việt Nam.

Nếu muốn vẽ bản đồ to nhỏ thì sửa scale_. Vd. scale_ = 2 thì bản đồ to gấp đôi. Nếu offsetX và offsetY tăng thì bản đồ sẽ dịch xuống dưới và dịch sang phải.

Trong tập tin dữ liệu cho Hà Nội đã được gộp từ Hà Nội cũ và Hà Tây cũ.

Code cũng đơn giản thôi. Toàn bộ code trong Module1
Mã:
Option Explicit

Sub create_map()
Const scale_ = 1
Const offsetX = 10
Const offsetY = 10
Dim firstRow As Long, lastRow As Long, chiso1 As Long, chiso2 As Long, curr_col As Long, k As Long, n As Long
Dim shp_name() As String, ten As String, Points(), shp As Shape
    ten = Sheet1.Range("A2").Value
    For k = 1 To 63
        If Sheet4.Cells(1, 2 * k - 1).Value = ten Then Exit For
    Next k
    If k > 63 Then
        Sheet1.Range("A2").Value = Empty    ' khong tim thay ten tinh nen xoa ten tinh
        chiso1 = 1
        chiso2 = 63
    Else
        chiso1 = k
        chiso2 = k
    End If
 
    For k = chiso1 To chiso2
        n = 0
        curr_col = 2 * k - 1
        firstRow = Rows.count
        Do While firstRow > 2
            lastRow = firstRow - 1
            lastRow = Sheet4.Cells(lastRow, curr_col + 1).End(xlUp).Row
            firstRow = Sheet4.Cells(lastRow, curr_col + 1).End(xlUp).Row
            n = n + 1
            ReDim Preserve shp_name(1 To n)
            Points = Sheet4.Range(Sheet4.Cells(firstRow, curr_col), Sheet4.Cells(lastRow, curr_col + 1)).Value
            shp_name(n) = create_shape(Sheet1, Points, UBound(Points, 1), scale_, offsetX, offsetY).Name
        Loop
        If UBound(shp_name) = 1 Then
            Set shp = Sheet1.Shapes(shp_name(1))
        Else
            Set shp = Sheet1.Shapes.Range(shp_name).Group
        End If
        With shp
            .Name = Sheet4.Cells(1, curr_col).Value
            .Fill.ForeColor.RGB = RGB(141, 180, 226)
            .Line.Weight = 0.25
            .Line.ForeColor.RGB = RGB(255, 255, 255)
            .Placement = xlMove
        End With
    Next k
End Sub

Private Function create_shape(sh As Worksheet, arrPolygon(), ByVal count As Long, ByVal scale_ As Double, ByVal offsetX As Double, ByVal offsetY As Double) As Shape
Dim r As Long
    For r = 1 To count
        arrPolygon(r, 1) = (arrPolygon(r, 1) + offsetX) * scale_
        arrPolygon(r, 2) = (arrPolygon(r, 2) + offsetY) * scale_
    Next r
    With sh
        With .Shapes.BuildFreeform(msoEditingCorner, arrPolygon(1, 1), arrPolygon(1, 2))
            For r = 2 To count
                .AddNodes msoSegmentLine, msoEditingAuto, arrPolygon(r, 1), arrPolygon(r, 2)
            Next r
            Set create_shape = .ConvertToShape
        End With
    End With
End Function
Vậy là đầy đủ rồi, cảm ơn chú rất nhiều.
Múi giở của chú rất ấn tượng và đặc biệt, phương xa chú giữ gìn sức khoẻ.
 

Bài viết mới nhất

Back
Top Bottom